RenderTester
The props must be specified, the initial state may be specified, and then all child workflows and workers that are expected to run, and any outputs from them, must be specified with expectWorkflow and (optionally) expectWorker and expectSideEffect calls. If one needs to verify all workers explicitly, perhaps to verify that a worker is not run, then use requireExplicitWorkerExpectations. Likewise requireExplicitSideEffectExpectations for side effects. Then call render and perform any assertions on the rendering. An event may also be sent to the rendering if no workflows or workers emitted an output. Lastly, the RenderTestResult returned by render
may be used to assert on the WorkflowActions processed to handle events or outputs by calling verifyAction or verifyActionResult.
All workflows that are rendered/ran by this workflow must be specified.
Workers are optionally specified. Specified workers must run. Unexpected workers on a render pass do not cause a test failure unless requireExplicitWorkerExpectations is true. Side effects are optionally specified. Specified side effects must run. Unexpected side effects on a render pass do not cause a test failure unless requireExplicitSideEffectExpectations is true.
It is an error if more than one workflow or worker specifies an output.
It is a test failure if any workflows or workers that were expected were not ran.
It is a test failure if the workflow tried to run any workflows that were not expected.
It is a test failure if no workflow or worker emitted an output, no rendering event was invoked, and any of the action verification methods on RenderTestResult is called.
Examples
Worker output
The following example tests a render pass that runs one worker, SubmitLoginWorker
, which is configured to have "emitted" an output, and one workflow, ChildWorkflow
, which expects a props containing "test@foo.com" and returning a ChildRendering
as its rendering.
It checks that the rendering properties are expected and that the output handler for the SubmitLoginWorker
returned the CompleteLogin
action.
workflow
.testRender(
props = MyProps(…),
initialState = MyState(…)
)
.expectWorker(
workerClass = SubmitLoginWorker::class
key = "signin",
output = WorkflowOutput(LoginResponse(success = true))
)
.expectWorkflow(
workflowType = ChildWorkflow::class,
key = "child",
assertProps = { assertThat(it.email).isEqualTo("test@foo.com") },
rendering = ChildRendering("message")
)
.render { rendering ->
assertThat(rendering.text).isEqualTo("foo")
}
.verifyAction { action ->
assertThat(action).isEqualTo(Action.CompleteLogin(success = true))
}
Rendering event
This is similar to the example above, but will test an event sent to the rendering instead.
workflow
.testRender(
props = MyProps(…),
initialState = MyState(…)
)
.expectWorker(
matchesWhen = { it is SubmitLoginWorker },
key = "signin"
)
.expectWorkflow(
workflowType = ChildWorkflow::class,
key = "child",
assertProps = { assertThat(it.email).isEqualTo("test@foo.com") },
rendering = ChildRendering("message")
)
.render { rendering ->
rendering.onCancelClicked()
assertThat(rendering.text).isEqualTo("foo")
}
.verifyAction { action ->
assertThat(action).isEqualTo(Action.CancelLogin)
}
Verify action result
This test verifies the action result instead of the action itself. This technique is useful if the WorkflowAction is anonymous or inline.
val currentState = …
val previousState = …
workflow
.testRender(
props = MyProps(…),
initialState = currentState
)
.render { rendering ->
rendering.onCancelClicked()
}
.verifyActionResult { newState, output ->
// Check that the workflow navigated back correctly.
assertThat(newState).isEqualTo(previousState)
// Check that the workflow didn't emit any output from the button click.
assertThat(output).isNull()
}
Too many outputs
This is an example of what not to do – this test will error out because a worker is emitting and output and a rendering event is sent.
workflow
.testRender(
props = MyProps(…),
initialState = MyState(…)
)
.expectWorker(
matchesWhen = { it is SubmitLoginWorker },
key = "signin",
output = WorkflowOutput(LoginResponse(success = true))
)
.expectWorkflow(
workflowType = ChildWorkflow::class,
key = "child",
assertProps = { assertThat(it.email).isEqualTo("test@foo.com") },
rendering = ChildRendering("message")
)
.render { rendering ->
// This will throw and fail the test because the SubmitLoginWorker is also configured to emit
// an output.
rendering.onCancelClicked()
Types
Describes a call to RenderContext.renderChild.
Functions
Specifies that this render pass is expected to run a side effect with a key that satisfies matcher. This expectation is strict, and will fail if multiple side effects match.
Specifies that this render pass is expected to run a particular side effect.
Specifies that this render pass is expected to run a Worker that has the same type of the given worker and for which the actual worker's doesSameWorkAs
method returns true. If a worker is ran that matches the type of expected, but the actual worker's doesSameWorkAs
returns false, then an AssertionError will be thrown. If you need to perform custom assertions, use the overload of this method that takes an assertWhen
parameter.
Specifies that this render pass is expected to run a Worker with the given workerClass. The worker's output type is not taken into consideration.
Specifies that this render pass is expected to run a Worker whose KType matches workerType.
Specifies that this render pass is expected to run a Worker with the given outputType.
Specifies that this render pass is expected to render a particular child workflow.
Execute the workflow's render
method and run block to perform assertions on and send events to the resulting rendering.