Skip to content

mocks: up for executeFlow #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions docs/plugins-v2/mocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ description: Safely and efficiently simulate behavior, verify interactions, and

# {{ page.title }}

- [Mock Behavior](#mock-behavior)
- [Usage](#usage)
- [Mock definition](#mock-definition)
- [Fields for Mocking a Task](#fields-for-mocking-a-task)
- [Fields for Mocking a Task Method](#fields-for-mocking-a-task-method)
- [How to mock a Task](#how-to-mock-a-task)
- [Example: Mocking a Task Call](#example-mocking-a-task-call)
- [Example: Mocking a Task Call and Executing a Flow Instead of the Original Task](#example-mocking-a-task-call-and-executing-a-flow-instead-of-the-original-task)
- [Example: Mocking a Task with Specific Input Parameters](#example-mocking-a-task-with-specific-input-parameters)
- [How to Mock a Task method](#how-to-mock-a-task-method)
- [Example: Mocking a Task Method](#example-mocking-a-task-method)
- [Example: Mocking a Task Method and Executing a Flow Instead of the Original Task method](#example-mocking-a-task-method-and-executing-a-flow-instead-of-the-original-task-method)
- [Example: Mocking a Task Method with Input Arguments](#example-mocking-a-task-method-with-input-arguments)
- [How to Verify Task Calls](#how-to-verify-task-calls)
- [Example: Verifying a Task Call](#example-verifying-a-task-call)
Expand All @@ -28,6 +34,15 @@ Mocks plugin allow you to:
Mocks help isolate individual components during testing, making tests faster, safer, and more
focused.

## Mock Behavior

- Mocked Tasks Emit Process [Events](../processes-v2/configuration.html#events). These events make the execution appear as if the original task was called;
- It is not possible to mock a task that does not exist;
- It is not possible to mock a method that does not exist in the original task;
- When a task is mocked, the original task is not created. This ensures that:
- The task's constructor or initialization logic does not execute;
- Any side effects or resource usage associated with task creation are avoided.

## Usage

To be able to use the task in a Concord flow, it must be added as a
Expand All @@ -39,6 +54,60 @@ configuration:
- mvn://com.walmartlabs.concord.plugins.basic:mock-tasks:{{ site.concord_core_version }}
```

## Mock definition

Mocks in Concord flows are defined as a `mocks` variable. This variable contains a list of mock definitions,
each describing how tasks or task methods should behave during testing.
The fields in a mock definition vary depending on whether you are mocking a task or a task method.

### Fields for Mocking a Task

The following fields are used when mocking a [task call step](../processes-v2/flows.html#task-calls).
These mocks are applied to steps where tasks are invoked.

| Field | Type | Description | Required |
|---------------|--------|-----------------------------------------------------------------------------------------------|----------|
| `task` | String | The name of the task being mocked | **Yes** |
| `in` | Object | Input parameters that the task must match for the mock to be applied. Used for mock selection | No |
| `stepName` | String | The name of the flow step where the task is invoked. Used for mock selection | No |
| `stepMeta` | Map | Metadata for the flow step. Used for mock selection | No |
| `out` | Map | The output to return from the task when this mock is applied | No |
| `throwError` | String | The error message to throw when this mock is applied | No |
| `executeFlow` | String | The name of a flow to execute instead of returning output or throwing an error | No |

Selection Criteria: A mock for a task is selected if:
- The task name matches;
- The in, stepName, and stepMeta fields (if provided) match the task invocation parameters.

Key Behavior of `executeFlow`
- The input parameters of the task are passed directly to the flow as-is. The flow can access these parameters directly by their original names;
- The result of the mocked task can be specified by defining the result variable in the flow.

### Fields for Mocking a Task Method

The following fields are used when mocking a [task method](../processes-v2/flows.html#expressions).
These mocks are applied to steps where specific methods of a task are invoked.

| Field | Type | Description | **Required** |
|---------------|--------|----------------------------------------------------------------------------------------------|--------------|
| `task` | String | The name of the task containing the method being mocked | **Yes** |
| `method` | String | The name of the method being mocked | **Yes** |
| `args` | List | The arguments that the method must match for the mock to be applied. Used for mock selection | No |
| `stepName` | String | The name of the flow step where the method is invoked. Used for mock selection | No |
| `stepMeta` | Map | Metadata for the flow step. Used for mock selection | No |
| `throwError` | String | The error message to throw when this mock is applied | No |
| `executeFlow` | String | The name of a flow to execute instead of returning output or throwing an error | No |
| `result` | Any | The result to return from the method when this mock is applied | No |

Selection Criteria: A mock for a task method is selected if:
- The task name matches;
- The task method matches;
- The args, stepName, and stepMeta fields (if provided) match the method invocation.

Key Behavior of `executeFlow`
- The method arguments are passed to the flow as a single variable named `args`. This variable contains a list of the method arguments;
- The result of the mocked task can be specified by defining the result variable in the flow.

## How to Mock a Task

You can mock specific tasks to simulate their behavior.
Expand Down Expand Up @@ -70,6 +139,38 @@ flows:
In `mainTest`, we set up a "mock" for the `myTask` task. This mock intercepts calls to any `myTask`
instance and overrides the output, setting the result to `42` instead of running the actual task.

### Example: Mocking a Task Call and Executing a Flow Instead of the Original Task

```yaml
flows:
main:
- task: myTask
in:
param1: "value"
out: taskResult

mainTest:
- set:
mocks:
# Mock the myTask task call
- task: "myTask"
executeFlow: myTaskAsAFlow

- call: main
out: taskResult

- log: "${taskResult}" # prints out 'result=42'

myTaskAsAFlow:
- log: "${param1}" # prints out `value`
- set:
result:
result: 42
```

In `mainTest`, we set up a "mock" for the `myTask` task. This mock intercepts calls to any `myTask`
instance and executes the `myTaskAsAFlow` flow instead of the original task.

### Example: Mocking a Task with Specific Input Parameters

```yaml
Expand Down Expand Up @@ -129,6 +230,41 @@ flows:
In `mainTest`, we set up a mock to only intercept `myTask.myMethod` calls.
When these parameter match, the mock replaces the task's output with `result: 42`

### Example: Mocking a Task Method and Executing a Flow Instead of the Original Task method

```yaml
flows:
main:
- expr: ${myTask.myMethod(1, "one")}
out: taskResult

mainTest:
- set:
mocks:
# Mock the myTask task call
- task: "myTask"
method: "myMethod"
args:
- 1
- "one"
executeFlow: myTaskMyMethodAsAFlow

- call: main
out: taskResult

- log: "${taskResult}" # prints out 'result=42'

myTaskMyMethodAsAFlow:
- log: "${args[0]}" # prints 1
- log: "${args[1]}" # prints "one"
- set:
result:
result: 42
```

In `mainTest`, we set up a mock to only intercept `myTask.myMethod` calls with input arguments [1, "one"].
When these parameter match, the mock executes the `myTaskMyMethodAsAFlow` flow instead of the original task method.

### Example: Mocking a Task Method with Input Arguments

```yaml
Expand Down