TIL

4. Integration Testing Application Modules

https://docs.spring.io/spring-modulith/reference/testing.html

package example.order

@ApplicationModuleTest
class OrderIntegrationTests {

  // Individual test cases go here
}
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v3.0.0-SNAPSHOT)

… - Bootstrapping @ApplicationModuleTest for example.order in mode STANDALONE (class example.Application)…
… - ======================================================================================================
… - ## example.order ##
… - > Logical name: order
… - > Base package: example.order
… - > Direct module dependencies: none
… - > Spring beans:
… -       + ….OrderManagement
… -       + ….internal.OrderInternal
… - Starting OrderIntegrationTests using Java 17.0.3 …
… - No active profile set, falling back to 1 default profile: "default"
… - Re-configuring auto-configuration and entity scan packages to: example.order.

부트스트랩 모드

효과적인 의존성 다루기

통합 테스트 시나리오 정의

@ApplicationModuleTest
class SomeApplicationModuleTest {

  @Test
  fun someModuleIntegrationTest(scenario: Scenario) {
    // Use the Scenario API to define your integration test
  }
}
// Start with an event publication
scenario.publish(MyApplicationEvent()).

// Start with a bean invocation
scenario.stimulate(() -> someBean.someMethod()).
.andWaitForEventOfType(SomeOtherEvent.class)
 .matching(event -> ) // Use some predicate here
 .
// Executes the scenario
.toArrive()

// Execute and define assertions on the event received
.toArriveAndVerify(event -> )
scenario.publish(new MyApplicationEvent())
  .andWaitForEventOfType(SomeOtherEvent::class)
  .matching(event -> )
  .toArriveAndVerify(event -> )
scenario.publish(new MyApplicationEvent())
  .andWaitForStateChange(() -> someBean.someMethod()))
  .andVerify(result -> )

Scenario 실행 커스터마이징

scenario.publish(MyApplicationEvent())
  .customize(it -> it.atMost(Duration.ofSeconds(2)))
  .andWaitForEventOfType(SomeOtherEvent::class)
  .matching(event -> )
  .toArriveAndVerify(event -> )
@ExtendWith(MyCustomizer::class)
class MyTests {

  @Test
  fun myTestCase(scenario : Scenario) {
    // scenario will be pre-customized with logic defined in MyCustomizer
  }

  class MyCustomizer : ScenarioCustomizer {

    override fun getDefaultCustomizer(method : Method, context : ApplicationContext) : Function<ConditionFactory, ConditionFactory> {
      return it -> 
    }
  }
}