轴突测试:缺少上下文
Axon Testing: Missing Context
在 Axon-SpringBoot 应用程序中,我有一个聚合,在其某些命令处理程序中使用注入的 DAO。
例如:
@Aggregate
class MyAggregate {
@CommandHandler
public MyAggregate (CreateMyAggregateCommand command, @Autowired MyAggregateDao dao) {
final SomeProperty = command.getSomePoprtery();
if (dao.findBySomeProperty(someProperty) == null) {
AggregateLifeCycle.apply(
new MyAggregateCreatedEvent(command.getIdentifier(),
someProperty);
} else {
// Don't create, already exits with some property
// report ...
}
}
}
像
这样的标准测试
@Test
void creationSucceeds () {
aggregateTestFixture = new AggregateTestFixture<>(MyAggregate.class);
final CreateMyAggregateCommand command = new CreateMyAggregateCommand(...);
final MyAggregateCreatedEvent = new MyAggregateCreatedEvent(...);
aggregateTestFixture
.givenNoPriorActivity()
.when(command)
.expectEvents(event);
}
失败:
org.axonframework.test.FixtureExecutionException: No resource of type
[com.xmpl.MyAggregateDao] has been registered. It is required
for one of the handlers being executed.
如何提供测试实施?
解决方案 1:模拟
由于这是关于单元测试的,而我的问题涉及数据库调用(外部服务),因此只要测试仅与孤立的聚合行为有关,模拟似乎就适用。
@Test
void creationSucceeds () {
aggregateTestFixture = new AggregateTestFixture<>(MyAggregate.class);
aggregateTestFixture.registerInjectableResource(
Mockito.mock(MyAggregateDao.class));
}
解决方案 2:真实注入 (jUnit 5)
这个适合我:
- 从 this github repo
获取用于 Spring jUnit5 测试支持的小型库
注释测试类:
@SpringBootTest(classes = {SpringTestConfig.class})
@ExtendWith(SpringExtension.class)
public class MyAggregateTest {
// ...
}
将application.properties放在src/test/resources
中
编写 Spring 测试配置,启动功能齐全的 Spring 容器:
@EnableAutoConfiguration
public class SpringTestConfig {
// Set up whatever you need
@Bean
@Autowired
MyAggregateDao myDao (DataSource dataSource) {
// ...
}
@Bean
@Autowired
EventStorageEngine eventStorageEngine () {
return new InMemoryEventStorageEngine();
}
}
直接注入你的测试,配置AggregateTestFixture
private AggregateTestFixture<MyAggregate> aggregateTestFixture;
@Autowired
private MyAggregateDao myDao;
@BeforeEach
void beforeEach () {
aggregateTestFixture = new AggregateTestFixture<>(MyAggregate.class);
// We still need to register resources manually
aggregateTestFixture.registerInjectableResource(myDao);
}
使用 jUnit 4
使用 jUnit 4 设置启动 Spring 容器的测试配置有点不同,但那里有足够的文档。开始 here
在 Axon-SpringBoot 应用程序中,我有一个聚合,在其某些命令处理程序中使用注入的 DAO。
例如:
@Aggregate
class MyAggregate {
@CommandHandler
public MyAggregate (CreateMyAggregateCommand command, @Autowired MyAggregateDao dao) {
final SomeProperty = command.getSomePoprtery();
if (dao.findBySomeProperty(someProperty) == null) {
AggregateLifeCycle.apply(
new MyAggregateCreatedEvent(command.getIdentifier(),
someProperty);
} else {
// Don't create, already exits with some property
// report ...
}
}
}
像
这样的标准测试@Test
void creationSucceeds () {
aggregateTestFixture = new AggregateTestFixture<>(MyAggregate.class);
final CreateMyAggregateCommand command = new CreateMyAggregateCommand(...);
final MyAggregateCreatedEvent = new MyAggregateCreatedEvent(...);
aggregateTestFixture
.givenNoPriorActivity()
.when(command)
.expectEvents(event);
}
失败:
org.axonframework.test.FixtureExecutionException: No resource of type
[com.xmpl.MyAggregateDao] has been registered. It is required
for one of the handlers being executed.
如何提供测试实施?
解决方案 1:模拟
由于这是关于单元测试的,而我的问题涉及数据库调用(外部服务),因此只要测试仅与孤立的聚合行为有关,模拟似乎就适用。
@Test
void creationSucceeds () {
aggregateTestFixture = new AggregateTestFixture<>(MyAggregate.class);
aggregateTestFixture.registerInjectableResource(
Mockito.mock(MyAggregateDao.class));
}
解决方案 2:真实注入 (jUnit 5)
这个适合我:
- 从 this github repo 获取用于 Spring jUnit5 测试支持的小型库
注释测试类:
@SpringBootTest(classes = {SpringTestConfig.class}) @ExtendWith(SpringExtension.class) public class MyAggregateTest { // ... }
将application.properties放在src/test/resources
中
编写 Spring 测试配置,启动功能齐全的 Spring 容器:
@EnableAutoConfiguration public class SpringTestConfig { // Set up whatever you need @Bean @Autowired MyAggregateDao myDao (DataSource dataSource) { // ... } @Bean @Autowired EventStorageEngine eventStorageEngine () { return new InMemoryEventStorageEngine(); } }
直接注入你的测试,配置
AggregateTestFixture
private AggregateTestFixture<MyAggregate> aggregateTestFixture; @Autowired private MyAggregateDao myDao; @BeforeEach void beforeEach () { aggregateTestFixture = new AggregateTestFixture<>(MyAggregate.class); // We still need to register resources manually aggregateTestFixture.registerInjectableResource(myDao); }
使用 jUnit 4
使用 jUnit 4 设置启动 Spring 容器的测试配置有点不同,但那里有足够的文档。开始 here