Skip to content

Support for scenarios to integration test application modules #136

@odrotbohm

Description

@odrotbohm

Working with application modules, and ones driven by @ApplicationEventListeners in particular introduces a couple of challenges:

  • Events stimulating the module need to be published in a transactional way. Thus, the test code is likely to require access to TransactionOperations and ApplicationEventPublisher.
  • As these events are usually handled asynchronously, an Awaitility pipeline will have to be set up.
  • Success or failure of an operation is usually determined by another event being published or some state change on the module being observed.
  • Additional verifications on the resulting event, the observed state changed, or stimulus result need to be performed

While all of this can be assembled using already existing abstractions, it would be nice if there was a way to formulate such scenarios in a readable API. An event-based scenario could look something like this:

scenario.publish(new ProductAdded(productId)) // <1>
  .andWaitAtMost(Duration.ofSeconds(2)) // <2>
  .forEventOfType(InventoryItemAdded.class) // <3>
  .toArriveAndVerify(it -> { // <4>
    assertThat(inventory.findByProductIdentifier(productId)).isPresent();
    assertThat(inventory.findById(it.id())).isPresent();
  });

<1> Stimulates the system through an event publication.
<2> (Optional) Customizations of the execution
<3> Define expectation by describing the event that's supposed to appear, optionally defining filters.
<4> (Optional) Formulate additional verifications. The most simple variant is toArrive().

Alternatively, the scenario could be described based on state changes.

scenario.stimulate(tx -> …) // <1>
  .forStateChange(() -> inventory.findByProductIdentifier(productId)) // <2>
  .andVerify(it -> { // <3>
    assertThat(it).…;
  });

<1> Would trigger some method of a module's service or the like. Access TransactionOperations to make sure that transactional event listeners are triggered for events potentially published during the operation.
<2> Inspect some state on the module. By default, accept a non-null (non-empty in the case of an Optional) as concluding.
<3> Additional verifications based on the value returned by the stimulus or expected changed state (out of <2>).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions