我很难弄清楚如何在Spring中编写单元测试。
这是我尝试测试的方法:
@Service
public class ActionRequestHandler {
@Autowired
private Vertx vertx;
@Autowired
private InventoryService inventoryService;
@Autowired
private RequestSerializationWrapper requestWrapper;
@Autowired
private ProducerTemplate producer;
@EventListener
@Transactional
public void registerConsumer(ApplicationReadyEvent event) {
EventBus eb = vertx.eventBus();
eb.consumer("bos.admin.wui.action", (Message<String> msg) -> {
handleIncomingRequest(msg);
});
}
// ...
}
到目前为止,我已经尝试在我的测试类中创建配置,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class ActionRequestHandlerTest {
@Configuration
static class ContextConfiguration {
@Bean
@Primary
public Vertx vertx() {
return Mockito.mock(Vertx.class);
}
@Bean
@Primary
public InventoryService inventoryService() {
return Mockito.mock(InventoryService.class);
}
@Bean
@Primary
public RequestSerializationWrapper requestWrapper() {
return new RequestSerializationWrapper();
}
}
@Autowired
private Vertx vertx;
@Autowired
private InventoryService inventoryService;
@Autowired
private RequestSerializationWrapper requestWrapper;
@Autowired
private ActionRequestHandler systemUnderTest;
@Test
public void registerConsumer_shouldRegisterVertxEventBusConsumer() {
EventBus eventBusMock = Mockito.mock(EventBus.class);
Mockito.when(vertx.eventBus()).thenReturn(eventBusMock);
systemUnderTest.registerConsumer(null);
Mockito.verify(eventBusMock.consumer(Matchers.anyString()), Mockito.times(1));
}
}
但是,这似乎试图解决 InventoryService 中的每个依赖项,而不是嘲笑整个类。当我运行时,上面的配置给了我这个错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private admin.messaging.converters.XmlToEntityConverter admin.persistence.service.InventoryService.entityConverter; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [admin.messaging.converters.XmlToEntityConverter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
我也尝试使用此处建议的配置文件。配置类看起来相同:
@Profile("test")
@Configuration
public class ActionRequestHandlerTestConfiguration {
@Bean
@Primary
public Vertx vertx() {
return Mockito.mock(Vertx.class);
}
@Bean
@Primary
public InventoryService inventoryService() {
return Mockito.mock(InventoryService.class);
}
@Bean
@Primary
public RequestSerializationWrapper requestWrapper() {
return new RequestSerializationWrapper();
}
}
测试的设置略有不同,而是使用以下注释:
@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ActionRequestHandler.class)
public class ActionRequestHandlerTest {
// ...
}
但这反而给了我一个错误,即 Vertx 无法连接:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private io.vertx.core.Vertx admin.messaging.request.ActionRequestHandler.vertx; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [io.vertx.core.Vertx] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
我怎样才能让它工作?我哪里出错了?
你不需要整个 spring 上下文来编写 ActionRequestHandler
的单元测试。您应该改用MockitoJunitRunner
并对依赖项进行模拟。
@RunWith(MockitoJunitRunner.class)
public class ActionRequestHandlerTest {
@Mock
private Vertx vertx;
@Mock
private InventoryService inventoryService;
@Mock
private RequestSerializationWrapper requestWrapper;
@Mock
private ProducerTemplate producer;
@InjectMocks
private ActionRequestHandler actionRequestHandler;
@Test
public void testRegisterConsumer() {
.... Your code to test ActionRequestHandler#registerConsumer will go here....
}
}
您可以在此处阅读有关它的更多信息。
尝试
@ContextConfiguration("/test-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
这会告诉 Junit 使用与测试位于同一目录中的 test-context.xml 文件。这个文件应该类似于真实的上下文.xml你用于 spring,但自然指向测试资源。