当我的jUnit测试结束时,我得到以下异常:
7 May 2014 18:06:29 INFO GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@7b0133c2: startup date [Tue May 27 18:06:09 IDT 2014]; root of context hierarchy
27 May 2014 18:06:29 INFO DefaultLifecycleProcessor - Stopping beans in phase 2147483647
27 May 2014 18:06:29 INFO NettyTcpClient - CLOSED: [id: 0x09b0bb52, /127.0.0.1:56869 :> /127.0.0.1:61613]
27 May 2014 18:06:31 ERROR StompBrokerRelayMessageHandler - Error while shutting down TCP client
java.util.concurrent.TimeoutException
at org.springframework.messaging.tcp.reactor.AbstractPromiseToListenableFutureAdapter.get(AbstractPromiseToListenableFutureAdapter.java:84)
at org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler.stopInternal(StompBrokerRelayMessageHandler.java:377)
at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.stop(AbstractBrokerMessageHandler.java:150)
at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.stop(AbstractBrokerMessageHandler.java:164)
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:229)
at org.springframework.context.support.DefaultLifecycleProcessor.access$300(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:363)
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:202)
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:118)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:888)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:809)
27 May 2014 18:06:31 INFO ThreadPoolTaskExecutor - Shutting down ExecutorService 'brokerChannelExecutor'
27 May 2014 18:06:31 INFO ThreadPoolTaskScheduler - Shutting down ExecutorService 'messageBrokerSockJsTaskScheduler'
27 May 2014 18:06:31 INFO ThreadPoolTaskExecutor - Shutting down ExecutorService 'clientOutboundChannelExecutor'
27 May 2014 18:06:31 INFO ThreadPoolTaskExecutor - Shutting down ExecutorService 'clientInboundChannelExecutor'
27 May 2014 18:06:31 INFO EhCacheManagerFactoryBean - Shutting down EhCache CacheManager
27 May 2014 18:06:31 INFO LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
27 May 2014 18:06:31 INFO DefaultContextLoadTimeWeaver - Removing all registered transformers for class loader: sun.misc.Launcher$AppClassLoader
有什么办法可以防止吗?
p。S -测试是成功的,但我真的不喜欢看到堆栈跟踪
编辑-我的测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/application-context.xml" })
public class EmptyTest{
/**
* Test (empty)
*/
@Test()
public void emptyTest() {
assertTrue(true);
}
}
这是我的配置文件的经纪人:
@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableStompBrokerRelay(
"/topic",
"/queue/");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(
"/wsdemo").withSockJS();
}
}
在我看来,您有几个选项,具体取决于您现在在测试中想要实现的目标,以及您将来可能希望能够实现的目标。
1)如果您的测试根本不需要websocket配置,请将其更改为指向不包含WebSocketConfig
的自定义上下文配置。
2)如果你的测试需要websocket配置,但你不需要代理中继(我看不出为什么在测试中需要它),你可以添加另一个使用registry.enableSimpleBroker("/topic", "/queue/")
而不是enableStompBrokerRelay
的测试配置。然后将没有到代理的TCP连接。这种方法的明显缺点是,您没有测试您的实际配置,并且您正在复制目标前缀。
3)为您的测试运行嵌入式STOMP代理。我不是100%确定存在这样的东西——我知道ActiveMQ支持STOMP,并且支持在VM中运行,但我没有尝试过STOMP。如果可能的话,这种方法的优点是您的测试将非常接近实际代码。
4)您可以自定义STOMP代理中继,使您能够完全控制应用程序从代理接收的内容。您可以自定义StompBrokerRelayMessageHandler
,它通过添加扩展DelegatingWebSocketMessageBrokerConfiguration
的Configuration类来管理到中继代理的连接,以便覆盖stompBrokerRelayMessageHandler()
方法。例如,您可以将它使用的TCP客户端设置为您自己的TcpOperations
实现。下面是一个简单的TCP客户端示例,它什么都不做,即使处理程序认为它已连接,但不能接收或发送消息。
@Override
public AbstractBrokerMessageHandler stompBrokerRelayMessageHandler() {
AbstractBrokerMessageHandler handler = super.stompBrokerRelayMessageHandler();
if (handler instanceof StompBrokerRelayMessageHandler) {
StompBrokerRelayMessageHandler stompHandler = (StompBrokerRelayMessageHandler) handler;
stompHandler.setTcpClient(new TcpOperations<byte[]>() {
@Override
public ListenableFuture<Void> connect(TcpConnectionHandler<byte[]> connectionHandler) {
return new CompletedListenableFuture<>(null);
}
@Override
public ListenableFuture<Void> connect(TcpConnectionHandler<byte[]> connectionHandler, ReconnectStrategy reconnectStrategy) {
return new CompletedListenableFuture<>(null);
}
@Override
public ListenableFuture<Void> shutdown() {
return new CompletedListenableFuture<>(null);
}
});
}
return handler;
}
请注意,CompletedListenableFuture
只是ListenableFuture
的一个实现,它在构造之后完成,并立即调用传递给addCallback
的任何回调,并将值传递给构造函数。
这里的要点是您可以轻松地定制代理中继组件的确切行为,因此您可以在测试中更好地控制它们。我不知道有什么内置的支持使这种测试更容易,但是websocket的支持仍然是很新的。我建议你看看Rossen Stoyanchev的优秀的例子项目spring-websocket-portfolio
,如果你还没有这样做的话,因为它包含了几个如何在不同级别测试websocket配置的例子(只有一个控制器,加载完整的上下文,运行嵌入式服务器,…)。希望这也有助于您决定如何测试您的应用程序,以及您可能需要自定义来完成它。