我目前正在使用 Axon 4.2,并且我有一个聚合(Customer),它在其 @CommandHandlers 中使用注入(inject)的服务(CustomerService)
方法。
下面显示了它的简化版本(但对于本示例仍然有效)。
@Aggregate
public class Customer {
@AggregateIdentifier
private Long id;
private String name;
private String address;
@CommandHandler
public Customer(CreateCommand command, CustomerService customerService) {
log.debug( customerService.doSomething(command.getId()));
AggregateLifecycle.apply(new CreatedEvent(command.getId(), command.getName()));
}
@CommandHandler
public void on(UpdateCommand command, CustomerService customerService){
log.debug( customerService.doSomething(command.getId()));
AggregateLifecycle.apply( new UpdatedEvent(command.getId(),command.getAddress()));
}
@EventSourcingHandler
public void on(CreatedEvent event){
this.id = event.getId();
this.name = event.getName();
}
@EventSourcingHandler
public void on(UpdatedEvent event){
this.address = event.getAddress();
}
}
这是相应的测试:
@RunWith(MockitoJUnitRunner.class)
public class CustomerTest {
@Mock
private CustomerService customerService;
private FixtureConfiguration<Customer> fixture;
@Before
public void setUp() {
fixture = new AggregateTestFixture<>(Customer.class);
fixture.registerInjectableResource(customerService);
}
@Test
public void testCreation(){
final Long id = 1L;
final String name = "Elmo";
when(customerService.doSomething(id)).thenReturn("called");
fixture.givenNoPriorActivity()
.when(new CreateCommand(id, name))
.expectEvents(new CreatedEvent(id, name));
verify(customerService).doSomething(id);
verifyNoMoreInteractions(customerService);
}
@Test
public void testUpdate(){
final Long id = 1L;
final String name = "Elmo";
final String address = "Sesame street";
when(customerService.doSomething(id)).thenReturn("called");
fixture.givenState(() -> new Customer(id, name, null))
.when(new UpdateCommand(id, address))
.expectEvents(new UpdatedEvent(id, address));
verify(customerService).doSomething(id);
verifyNoMoreInteractions(customerService);
}
}
代码工作正常,但测试存在问题。 事实上,testCreation() 测试通过,但 testUpdate() 测试失败并出现以下错误。
org.axonframework.test.FixtureExecutionException:
No resource of type [CustomerService] has been registered. It is required for one of the handlers being executed.
at org.axonframework.test.FixtureResourceParameterResolverFactory$FailingParameterResolver.resolveParameterValue(FixtureResourceParameterResolverFactory.java:58)
at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMember.resolveParameterValues(AnnotatedMessageHandlingMember.java:156)
at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMember.handle(AnnotatedMessageHandlingMember.java:132)
at org.axonframework.messaging.annotation.WrappedMessageHandlingMember.handle(WrappedMessageHandlingMember.java:61)
at org.axonframework.modelling.command.inspection.AnnotatedAggregate.handle(AnnotatedAggregate.java:427)
at org.axonframework.modelling.command.inspection.AnnotatedAggregate.lambda$handle$3(AnnotatedAggregate.java:400)
at org.axonframework.messaging.Scope.executeWithResult(Scope.java:111)
...
如果我删除 on UpdateCommand 方法中的 CustomerService 参数(以及相关代码),则 testUpdate() 测试通过,因此问题似乎出在依赖注入(inject)中。
最佳答案
聚合是 DomainDrivenDesign ( https://axoniq.io/resources/domain-driven-design ) 中的重要战术模式(主要构建 block )。在 Axon 中,聚合接受业务命令,这通常会产生与业务领域相关的事件——领域事件。首先,您不应该将逻辑委托(delegate)给某些外部 CustomerService
服务。您可以在 Axon Reference guide. 上找到有关如何设计聚合的更多详细信息。此外,this chapter提供带注释的消息处理函数的所有可能参数的详尽列表。
关于java - Axon 夹具注入(inject)在 @CommandHandler 注解的方法中失败(构造函数除外),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57937797/