如何在使用 Axon 框架时模拟 Spring 引导存储库
How to mock Spring Boot repository while using Axon framework
我目前正在尝试使用 Axon 框架和 Spring Boot 实现一些应用程序,我需要为其中一个 sagas 编写单元测试。
在这个传奇中,除了 axon 的功能外,我还使用 spring 引导存储库,我需要模拟它以进行测试。
问题是,存储库没有被注入——它总是空的。
我真的很感激在这件事上的任何帮助。
在下面找到发布类:
传奇:
@Slf4j
@Saga
@Service
public class ValidationSaga {
@Autowired
private transient CommandGateway commandGateway;
private EmployeeRepository employeeRepository;
private String correlationId;
private String emp1Code;
private String emp2Code;
private String emp1Id;
private String emp2Id;
private String emp3Id;
private String emp3Code;
@StartSaga
@SagaEventHandler(associationProperty = "correlationId")
public void on(NewMatchingDocumentAggregate.MatchingSubmittedEvent event) {
log.debug(">>> HANDLING IN SAGA");
log.debug(">>> REPO: ", employeeRepository); //At this point repo is null
this.correlationId = event.getCorrelationId();
this.emp1Code= event.getEmp1Code();
this.emp2Code= event.getEmp2Code();
this.emp1Id= event.getEmp1Id();
this.emp2Id= event.getEmp2Id();
this.emp3Id= event.getEmp3Id();
this.emp3Code= event.getEmp3Code();
if(!employeeRepository.existsById(event.getEmp1Id())) {
employeeRepository.save(EmployeeEntity.builder()
.employeeCode(event.getEmp1Code())
.employeeName(null)
.isActive(true)
.removeFromRole(false)
.build());
}
if(!employeeRepository.existsById(event.getEmp2Id())) {
employeeRepository.save(EmployeeEntity.builder()
.employeeCode(event.getEmp2Code())
.employeeName(null)
.isActive(true)
.removeFromMentorRole(false)
.build());
}
log.debug(">>> > before gateway");
commandGateway.send(new NewMatchingDocumentAggregate.ApplyContextCommand(
this.correlationId, this.emp1Code, this.emp2Code, this.emp1Id, this.emp2Id,
this.emp3Id, this.emp3Code));
}
@EndSaga
@SagaEventHandler(associationProperty = "correlationId")
public void on(NewMatchingDocumentAggregate.MatchingDefinedEvent event) {
}
}
测试:
@Slf4j
@RunWith(MockitoJUnitRunner.class)
public class ValidationSagaTest {
@Mock
private EmployeeRepository employeeRepository;
@InjectMocks
private ValidationSaga validationSaga;
private FixtureConfiguration fixture;
@Before
public void setUp() throws Exception {
fixture = new SagaTestFixture<>(ValidationSaga.class);
}
@Test
public void shouldSendApplyContextCommand_whenEmployeesExists_givenSomeEvent() {
val correlationId = "correlationId";
val emp1Code = "emp1Code ";
val emp2Code = "emp2Code ";
val emp1Id = "emp1Id ";
val emp2Id = "emp2Id ";
val emp3Id = "emp3Id ";
val emp3Code = "emp3Code ";
when(employeeRepository.existsById(emp1Id)).thenReturn(true);
when(employeeRepository.existsById(emp2Id)).thenReturn(true);
fixture.givenNoPriorActivity()
.whenAggregate(correlationId)
.publishes(new NewMatchingDocumentAggregate.MatchingSubmittedEvent(correlationId, emp1Code,
emp2Code, emp1Id, emp2Id, emp3Id, emp3Code))
.expectActiveSagas(1)
.expectDispatchedCommands(new NewMatchingDocumentAggregate.ApplyContextCommand(correlationId,
emp1Code, emp2Code, emp1Id, emp2Id, emp3Id, emp3Code));
}
Axon 中的 Saga
不是 Spring 托管 Bean,尽管使用 @Autowired
注释在其中连接 Bean 的可能性确实使它看起来如此。
为了在您的 Saga 中连接 Beans,该框架使用 ResourceInjector
的实现,更具体地说是 SpringResourceInjector
.
现在这些信息不一定能解决您的问题,但可能会提示您需要做一些特定的事情来在您的 Saga 中注入模拟服务。为了能够使用您的模拟服务,您需要调用 SagaTestFixture#registerResource(Object)
函数,其中提供的 Object
是您的模拟服务。
我建议 setUp()
是根据您的情况注册这些资源的理想场所。
希望对您有所帮助!
我目前正在尝试使用 Axon 框架和 Spring Boot 实现一些应用程序,我需要为其中一个 sagas 编写单元测试。 在这个传奇中,除了 axon 的功能外,我还使用 spring 引导存储库,我需要模拟它以进行测试。
问题是,存储库没有被注入——它总是空的。 我真的很感激在这件事上的任何帮助。
在下面找到发布类:
传奇:
@Slf4j
@Saga
@Service
public class ValidationSaga {
@Autowired
private transient CommandGateway commandGateway;
private EmployeeRepository employeeRepository;
private String correlationId;
private String emp1Code;
private String emp2Code;
private String emp1Id;
private String emp2Id;
private String emp3Id;
private String emp3Code;
@StartSaga
@SagaEventHandler(associationProperty = "correlationId")
public void on(NewMatchingDocumentAggregate.MatchingSubmittedEvent event) {
log.debug(">>> HANDLING IN SAGA");
log.debug(">>> REPO: ", employeeRepository); //At this point repo is null
this.correlationId = event.getCorrelationId();
this.emp1Code= event.getEmp1Code();
this.emp2Code= event.getEmp2Code();
this.emp1Id= event.getEmp1Id();
this.emp2Id= event.getEmp2Id();
this.emp3Id= event.getEmp3Id();
this.emp3Code= event.getEmp3Code();
if(!employeeRepository.existsById(event.getEmp1Id())) {
employeeRepository.save(EmployeeEntity.builder()
.employeeCode(event.getEmp1Code())
.employeeName(null)
.isActive(true)
.removeFromRole(false)
.build());
}
if(!employeeRepository.existsById(event.getEmp2Id())) {
employeeRepository.save(EmployeeEntity.builder()
.employeeCode(event.getEmp2Code())
.employeeName(null)
.isActive(true)
.removeFromMentorRole(false)
.build());
}
log.debug(">>> > before gateway");
commandGateway.send(new NewMatchingDocumentAggregate.ApplyContextCommand(
this.correlationId, this.emp1Code, this.emp2Code, this.emp1Id, this.emp2Id,
this.emp3Id, this.emp3Code));
}
@EndSaga
@SagaEventHandler(associationProperty = "correlationId")
public void on(NewMatchingDocumentAggregate.MatchingDefinedEvent event) {
}
}
测试:
@Slf4j
@RunWith(MockitoJUnitRunner.class)
public class ValidationSagaTest {
@Mock
private EmployeeRepository employeeRepository;
@InjectMocks
private ValidationSaga validationSaga;
private FixtureConfiguration fixture;
@Before
public void setUp() throws Exception {
fixture = new SagaTestFixture<>(ValidationSaga.class);
}
@Test
public void shouldSendApplyContextCommand_whenEmployeesExists_givenSomeEvent() {
val correlationId = "correlationId";
val emp1Code = "emp1Code ";
val emp2Code = "emp2Code ";
val emp1Id = "emp1Id ";
val emp2Id = "emp2Id ";
val emp3Id = "emp3Id ";
val emp3Code = "emp3Code ";
when(employeeRepository.existsById(emp1Id)).thenReturn(true);
when(employeeRepository.existsById(emp2Id)).thenReturn(true);
fixture.givenNoPriorActivity()
.whenAggregate(correlationId)
.publishes(new NewMatchingDocumentAggregate.MatchingSubmittedEvent(correlationId, emp1Code,
emp2Code, emp1Id, emp2Id, emp3Id, emp3Code))
.expectActiveSagas(1)
.expectDispatchedCommands(new NewMatchingDocumentAggregate.ApplyContextCommand(correlationId,
emp1Code, emp2Code, emp1Id, emp2Id, emp3Id, emp3Code));
}
Axon 中的 Saga
不是 Spring 托管 Bean,尽管使用 @Autowired
注释在其中连接 Bean 的可能性确实使它看起来如此。
为了在您的 Saga 中连接 Beans,该框架使用 ResourceInjector
的实现,更具体地说是 SpringResourceInjector
.
现在这些信息不一定能解决您的问题,但可能会提示您需要做一些特定的事情来在您的 Saga 中注入模拟服务。为了能够使用您的模拟服务,您需要调用 SagaTestFixture#registerResource(Object)
函数,其中提供的 Object
是您的模拟服务。
我建议 setUp()
是根据您的情况注册这些资源的理想场所。
希望对您有所帮助!