Rule Context Generator
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}