我在尝试集成测试jms侦听器时遇到了一个问题 Mockito
以及 MockRestServiceServer
. 即使我用的是正确的 Mockito.when
注解,它们将显示为null MockRestServiceServer
就好像没人叫它一样。如果我改为测试 myService
jms侦听器调用的组件、mock和 MockRestServiceServer
电话工作如预期,这是令人费解的。我正在连接到一个嵌入式activemq代理进行测试,如果有帮助的话,我将使用springboot2.2.8.release和jdk8.x。
下面是jms侦听器类
@Component
public class MyJmsListener {
@Autowired
private MyService myService;
@JmsListener(
destination = "${jms.queue}",
containerFactory = "myJmsListenerContainerFactory"
)
public void receive(Message<String> message) {
myService.process(message);
}
}
下面是jms侦听器测试类
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class JmsListenerTest {
...
@MockBean
private AuthorizationService authorizationService;
...
@Autowired
private MockRestServiceServer mockRestServiceServer;
@Autowired
private JmsTemplate listenerTestJmsTemplate;
@Value("${jms.queue}")
private String testDestination;
...
@Test
public void testListener() throws IOException, URISyntaxException, InterruptedException {
//ARRANGE
String payloadPath = "classpath:payloads/listenerPayload.json";
String payload = new String(Files.readAllBytes(ResourceUtils.getFile(payloadPath).toPath()));
String testAuth = "auth";
Mockito.when(authorizationService.generateTicket(Mockito.any(Headers.class), Mockito.eq("9130353887051456")))
.thenReturn(testAuth);
String extPayloadPath = "classpath:payloads/revokeCancelAutoRenewRequestApi.json";
String extPayload = new String(Files.readAllBytes(ResourceUtils.getFile(extPayloadPath).toPath()));
mockRestServiceServer.expect(ExpectedCount.once(), MockRestRequestMatchers.requestTo(new URI("/test/v3/subscriptions/400367048/something")))
.andExpect(MockRestRequestMatchers.content().string(extPayload))
.andExpect(MockRestRequestMatchers.header(HttpHeaders.AUTHORIZATION, testAuth))
.andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK));
//ACT
listenerTestJmsTemplate.convertAndSend(testDestination, payload);
//ASSERT
mockRestServiceServer.verify();
Assert.assertTrue(JmsListenerWrapperConfiguration.latch.await(5, TimeUnit.SECONDS));
}
...
}
我有一个jmslistenerwrapperconfiguration,它允许我将倒计时锁存器 Package 到jms侦听器中。
@Configuration
@Profile("test")
public class JmsListenerWrapperConfiguration {
public static final CountDownLatch latch = new CountDownLatch(1);
@Bean
public JmsTemplate listenerTestjmsTemplate(ActiveMQConnectionFactory activeMQConnectionFactory){
JmsTemplate jmsTemplate = new JmsTemplate(activeMQConnectionFactory);
return jmsTemplate;
}
/**
* Wrap the JMS Listeners with a count down latch that will allow us to unit test them.
* @return The bean post processor that will wrap the JMS Listener.
*/
@Bean
public static BeanPostProcessor listenerWrapper() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyJmsListener) {
MethodInterceptor interceptor = new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = invocation.proceed();
if (invocation.getMethod().getName().equals("listen")) {
latch.countDown();
}
return result;
}
};
if (AopUtils.isAopProxy(bean)) {
((Advised) bean).addAdvice(interceptor);
return bean;
}
else {
ProxyFactory proxyFactory = new ProxyFactory(bean);
proxyFactory.addAdvice(interceptor);
return proxyFactory.getProxy();
}
}
else {
return bean;
}
}
};
}
}
mockrestserviceserver配置在这里定义。
@Configuration
@Profile("test")
public class MockRestServiceServerConfiguration {
@Bean
public MockRestServiceServer mockRestServiceServer(RestTemplate restTemplate) {
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate);
MockRestServiceServer server = builder.bufferContent().build();
return server;
}
}
我看到的错误如下。
java.lang.AssertionError: Further request(s) expected leaving 1 unsatisfied expectation(s).
0 request(s) executed.
at org.springframework.test.web.client.AbstractRequestExpectationManager.verify(AbstractRequestExpectationManager.java:159)
at org.springframework.test.web.client.MockRestServiceServer.verify(MockRestServiceServer.java:116)
更新
我一直在调试,当然测试是在线程[main]上运行的,而jms侦听器是在线程[defaultmessagelistenercontainer-1]上运行的,所以我的问题变成了,当mock/verification需要由不同的线程使用时,我们应该如何处理mockito mocking?
1条答案
按热度按时间ttisahbt1#
结果发现
MockRestServiceServer
需要在闩锁等待后进行验证,如下面的代码所示。