Fluent Commerce Logo
Docs
Sign In

Rule Context Generator

Essential knowledge

Author:

Kirill Gaiduk

Changed on:

5 Sept 2025

Overview

The `RuleContextGenerator` is the underlying class that the `RuleExecutor` and `WorkflowExecutor` use to construct a mock `Context` for your tests. While you will most often interact with it through the executors, you can also use it directly to manually create a `Context` object.

This is particularly useful when you are unit testing a helper or utility class that requires a `Context` object as a parameter, but you don't need to execute a full rule.

Key points

  • Core Context Builder`RuleContextGenerator` is the fundamental builder class that the `RuleExecutor` and `WorkflowExecutor` use to create the mock `Context` for your tests.
  • Direct Instantiation: You can use it directly (`RuleContextGenerator.of(...)`) when you need a `Context` object for testing a helper class or utility method, but don't need to execute a full rule.
  • Action Tracking: It automatically captures and tracks all actions (events, mutations, logs) performed during execution, providing methods like `getActionsOfType()` and `getLastActionOfType()` for verification.
  • Foundation of Testing: It is the foundational component of the test utilities, providing the mock environment that makes isolated unit and integration testing possible.

Core Methods

`of` (Event, MockApiClient)

To create a `Context` manually with a specific event and mock API client, use the static factory `RuleContextGenerator.of(event, mockApiClient)`.

1MockApiClient mockApi = new MockApiClient();
2Event testEvent = Event.builder()
3    .name("OrderCreated")
4    .entityRef("order-123")
5    .build();
6
7RuleContextGenerator contextGenerator = RuleContextGenerator.of(testEvent, mockApi.get());
`of` (MockApiClient)

To create a `Context` manually with a specific mock API client, use the static factory `RuleContextGenerator.of( mockApiClient)`.

1MockApiClient mockApi = new MockApiClient();
2RuleContextGenerator contextGenerator = RuleContextGenerator.of(mockApi.get());
`forRule`

To configure the context for a specific rule instance, use the `forRule()` method. This sets up the rule properties and configuration.

1RuleInstance ruleInstance = RuleInstance.builder()
2    .name("sampleRule")
3    .props(ImmutableMap.of("eventName", "my-custom-event"))
4    .build();
5
6RuleContextGenerator.RuleTestContext ruleContext = contextGenerator.forRule(ruleInstance);
`mockApiClient`

To replace the executor's default API mock with your own, use the `RuleContextGenerator.mockApiClient` method. This allows you to reuse the same mocks across different tests.

1// Manually create a MockApiClient for full control over API responses during the test
2final MockApiClient api = new MockApiClient();
3
4// Inject the custom MockApiClient into the current RuleContextGenerator
5RuleContextGenerator ruleContextGenerator = RuleContextGenerator.mockApiClient(api)
`getActions`

To retrieve the actions produced during execution, use the `RuleContextGenerator.getActions` method:

1// Retrieve all actions produced during rule execution for validation
2List<Action> actions = ruleContextGenerator.getActions()
`getActionsOfType`

To retrieve the actions produced during execution filtered by a specific type, use the `RuleContextGenerator.getActionsOfType` method:

1RuleContextGenerator context = RuleExecutor.of(
2        TestSendEvent.class,
3        ImmutableMap.of(EVENT_NAME, "success")
4    )
5    .execute();
6List<SendEventAction> sendEventActions = context.getActionsOfType(SendEventAction.class);
7assertEquals(sendEventActions.size(), 1);
`getFirstActionOfType`

To retrieve the first action of a given type that was produced during execution, use the `RuleContextGenerator.getFirstActionOfType` method:

1RuleContextGenerator context = RuleExecutor.of(
2        TestSendWebhook.class, 
3        ImmutableMap.of("endpoint", "http://fluentcommerce.com")
4    )
5    .execute();
6WebhookAction firstWebhookAction = context.getFirstActionOfType(WebhookAction.class);
7assertEquals(firstWebhookAction.getEvent().getName(), "my-webhook");
`getLastActionOfType`

To retrieve the last action of a given type that was produced during execution, use the `RuleContextGenerator.getLastActionOfType` method:

1RuleContextGenerator context = RuleExecutor.of(
2        TestSendWebhook.class, 
3        ImmutableMap.of("endpoint", "http://fluentcommerce.com")
4    )
5    .execute();
6WebhookAction lastWebhookAction = context.getLastActionOfType(WebhookAction.class);
7assertEquals(lastWebhookAction.getWebhookEndpoint(), "http://fluentcommerce.com");

Complete Example

Here's a complete example showing how to use `RuleContextGenerator` directly:

1import com.fluentcommerce.util.test.executor.RuleContextGenerator;
2import com.fluentcommerce.util.test.executor.MockApiClient;
3import com.fluentretail.rubix.context.Context;
4import com.fluentretail.rubix.event.Event;
5import com.fluentretail.rubix.rule.RuleInstance;
6import org.junit.jupiter.api.Test;
7
8import static com.fluentcommerce.util.test.executor.TestActions.SendEventAction;
9import static org.junit.jupiter.api.Assertions.*;
10
11public class MyUtilityTest {
12
13    @Test
14    void testMyUtilityMethod() {
15        // 1. CREATE: Set up the mock API client
16        MockApiClient mockApi = new MockApiClient();
17        
18        // 2. CREATE: Create the event
19        Event testEvent = Event.builder()
20            .name("OrderCreated")
21            .entityRef("order-123")
22            .entityType("ORDER")
23            .attributes(ImmutableMap.of(
24                "orderValue", "150.00",
25                "customerType", "PREMIUM"
26            ))
27            .build();
28
29        // 3. CREATE: Create the RuleContextGenerator
30        RuleContextGenerator contextGenerator = RuleContextGenerator.of(testEvent, mockApi.get());
31
32        // 4. CONFIGURE: Set up the rule instance
33        RuleInstance ruleInstance = RuleInstance.builder()
34            .name("MyTestRule")
35            .props(ImmutableMap.of(
36                "eventName", "success-event",
37                "threshold", "100"
38            ))
39            .build();
40
41        // 5. CONFIGURE: Configure the context for the rule
42        RuleContextGenerator.RuleTestContext ruleContext = contextGenerator.forRule(ruleInstance);
43
44        // 6. BUILD: Create the final Context object
45        Context context = contextGenerator.build();
46
47        // 7. EXECUTE: Run your utility method or rule
48        MyUtilityClass utility = new MyUtilityClass();
49        utility.processOrder(context);
50
51        // 8. VERIFY: Check the results
52        assertEquals(1, contextGenerator.getActionsOfType(SendEventAction.class).size());
53        assertEquals("success-event", contextGenerator.getLastActionOfType(SendEventAction.class).getEvent().getName());
54    }
55}