AWS Step Functions simulator for unit testing state machines
npm install sfn-simThis library simulates the AWS Step Functions runtime to unit test state machines, a lightweight
alternative to integration testing with LocalStack.
``sh`
npm install --save-dev sfn-sim
Import the load function, load your state machine, then execute with some input:
`js
import { load } from 'sfn-sim';
const stateMachine = load(definition, resources, options);
await stateMachine.execute(input);
`
See below for details on these parameters.
This must be a JSON object which is the Definition property of a state machine, which contains theStartAt and States fields at its root.
By default, your definition will be validated using statelint;
this can be disabled with the validateDefinition option set to false.
Note that CloudFormation functions and refs are not supported; you should replace these in your
definition before loading it.
This should be an array of objects which are AWS resources used by any Task steps in your stateservice
machine. Each object must contain and name fields, and additional fields depending on
the service.
The supported service values are listed below with their requirements, as well as an example using
the Lambda and S3 services.
This resource must contain a function field which must be a function. This will be executed as
your lambda handler.
Lambdas can support custom error handling as long as the name property has been set.
This resource must contain an objects field which must be an array. This can optionally bekey
pre-populated with objects, which must contain and body fields.
This resource must contain a messages field which must be an array.
This resource must contain a messages field which must be an array.
This resource must contain a metrics field which must be an array.
This resource must contain a stateMachine field which must be a function. This will be executed as
your state machine.
`js
const definition = {
StartAt: 'CalculateSquare',
States: {
CalculateSquare: {
Type: 'Task',
Resource: 'arn:aws:lambda:::function:calculate-square',
InputPath: '$.value',
ResultPath: '$.value',
Next: 'SaveToS3',
},
SaveToS3: {
Type: 'Task',
Resource: 'arn:aws:states:::aws-sdk:s3:putObject',
Parameters: {
Bucket: 'squared-numbers',
'Key.$': '$.number',
'Body.$': '$.value',
},
End: true,
},
},
};
const bucketObjects = [];
const resources = [
{
service: 'lambda',
name: 'calculate-square',
function: (x) => x * x,
},
{
service: 's3',
name: 'squared-numbers',
objects: bucketObjects,
},
];
const stateMachine = load(definition, resources);
test('writes a squared number to S3', async () => {
await stateMachine.execute({
number: 'three',
value: 3,
});
expect(bucketObjects).toContainEqual({
key: 'three',
body: 9,
});
});
`
The simulator supports Task steps that use the Wait for a Callback with Task Token
pattern.
When the Resource field of a Task step is suffixed with .waitForTaskToken, the correspondingtaskCallback
resource you provide to the simulator must include a function. This function receivestaskCallback
the Task's input and output as arguments, and its return value is used as the final result of the
Task. The function may throw an error to simulate notifying the state machine of task
failure.
`js
const definition = {
QueryLanguage: 'JSONata',
StartAt: 'AsyncAdd',
States: {
AsyncAdd: {
Type: 'Task',
Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken',
Arguments: {
FunctionName: 'start-async-add',
Payload: {
number: 1,
taskToken: '{% $states.context.Task.Token %}',
},
},
End: true,
},
},
};
const resources = [
{
service: 'lambda',
name: 'start-async-add',
function: (input) => ({ number: input.number + 1 }),
taskCallback: (_taskInput, taskOutput) => ({ number: taskOutput.number + 1 }),
},
];
const stateMachine = load(definition, resources, { validateDefinition: false });
test('waits for async task completion', async () => {
const result = await stateMachine.execute();
expect(result).toEqual({
number: 3,
});
});
`
This should be an object which can be used to override the default configuration of the simulator.
| Key | Description | Default |
| --- | ----------- | ------- |
| validateDefinition | Whether the provided definition should be validated on load | true |simulateWait
| | Whether any Wait steps should wait in real-time, otherwise passing immediately | false |stateMachineName
| | Identifier for the state machine, passed to the context object | undefined |executionName
| | Identifier for the execution, passed to the context object | undefined |
This library supports most available features of Step Functions. Some functionality has not been
implemented yet, including:
* Some AWS resources in Task` steps
* Some runtime error handling and data validation