TestStore aids in writing expressive and exhaustive tests for features built in the Composable Architecture. It allows you to send a sequence of actions to the store, and each step of the way you must assert exactly how state changed, and how effect emissions were fed back into the system.
Class Definition
Initialization
Creates a test store with an initial state and a reducer powering its runtime.Parameters:
initialState: The state the feature starts inreducer: The reducer that powers the runtime of the featureprepareDependencies: A closure that can be used to override dependencies that will be accessed during the testfileID: The fileIDfilePath: The filePathline: The linecolumn: The column
Properties
The current state of the test store.When read from a trailing closure assertion in
send or receive, it will equal the inout state passed to the closure.The current dependencies of the test store.The dependencies define the execution context that your feature runs in. They can be modified throughout the test store’s lifecycle in order to influence how your feature produces effects.
The current exhaustivity level of the test store.Defaults to
.on. Can be set to .off or .off(showSkippedAssertions: true) for non-exhaustive testing.The default timeout used in all methods that take an optional timeout.This is the default timeout used in methods like
receive and finish.Methods
Sending Actions
Sends an action to the store and asserts when state changes.To assert on how state changes you can provide a trailing closure, and that closure is handed a mutable variable that represents the feature’s state before the action was sent. You need to mutate that variable so that it is equal to the feature’s state after the action is sent.Parameters:
action: An actionupdateStateToExpectedResult: A closure that asserts state changed by sending the action to the store. The mutable state sent to this closure must be modified to match the state of the store after processing the given action. Do not provide a closure if no change is expected.
TestStoreTask that represents the lifecycle of the effect executed when sending the action.Receiving Actions
Asserts an action was received from an effect and asserts how the state changes.When an effect is executed in your feature and sends an action back into the system, you can use this method to assert that fact, and further assert how state changes after the effect action is received.Parameters:
expectedAction: An action expected from an effectduration: The amount of time to wait for the expected actionupdateStateToExpectedResult: A closure that asserts state changed by sending the action to the store
Finishing Tests
Suspends until all in-flight effects have finished, or until it times out.Can be used to assert that all effects have finished.Parameters:
duration: The amount of time to wait before asserting
State Assertions
Assert against the current state of the store.The trailing closure provided is given a mutable argument that represents the current state, and you can provide any mutations you want to the state. If your mutations cause the argument to differ from the current state of the test store, a test failure will be triggered.This tool is most useful in non-exhaustive test stores.Parameters:
updateStateToExpectedResult: A closure that asserts against the current state of the test store
Dependency Overrides
Overrides the store’s dependencies for a given operation.Parameters:
updateValuesForOperation: A closure for updating the store’s dependency values for the duration of the operationoperation: The operation
Overrides the store’s exhaustivity for a given operation.Parameters:
exhaustivity: The exhaustivityoperation: The operation
Usage Examples
Basic Test
Testing Effects
Non-Exhaustive Testing
Overriding Dependencies Mid-Test
Exhaustive Testing
By default,TestStore requires you to exhaustively prove how your feature evolves:
- After each action is sent you must describe precisely how the state changed
- If an effect sends an action back into the system, you must explicitly assert that you expect to receive that action
- All effects must complete by the time the test case has finished running
Non-Exhaustive Testing
Setexhaustivity to .off to allow:
- Asserting on a subset of state changes
- Sending actions even when there are unasserted received actions
- Finishing tests with in-flight effects
.off(showSkippedAssertions: true) to see what assertions are being skipped without causing test failures.
Type Aliases
A convenience type alias for referring to a test store of a given reducer’s domain.Instead of specifying two generics:You can specify a single generic: