我很难弄清楚如何在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)}
我还尝试使用建议here的配置文件。配置类看起来相同:
@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)}
我怎样才能让它发挥作用?我哪里错了?
答案 0 :(得分:1)
您不需要整个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....
}
}
您可以详细了解here。
答案 1 :(得分:0)
尝试
@ContextConfiguration("/test-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
这告诉Junit在测试的同一目录中使用test-context.xml文件。这个文件应该类似于你在春天使用的真正的context.xml,但是自然地指向测试资源。