Java 如何正确模拟WebSocket会话?

Java 如何正确模拟WebSocket会话?,java,unit-testing,spring-boot,junit,mockito,Java,Unit Testing,Spring Boot,Junit,Mockito,我使用springBoot创建了一个简单的websocket应用程序。我是Mockito的新手,我正在尝试用Mockito和junit对下面的类进行单元测试 @Component public class TextHandler extends TextWebSocketHandler { WebSocketSession session; @Override public void handleTextMessage(WebSocketSession session, TextMessag

我使用springBoot创建了一个简单的websocket应用程序。我是Mockito的新手,我正在尝试用Mockito和junit对下面的类进行单元测试

@Component
public class TextHandler extends TextWebSocketHandler {

WebSocketSession session;

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
        throws InterruptedException, IOException {

        // send message
        if (session.isOpen()) {
            try {

                session.sendMessage(new TextMessage("Hello from the websocket"));
            } finally {
                session.close();
            }
        } else {
            System.out.println("no open session available");
        }
}
我为测试包下的会话创建了一个存根,如下所示

@Component
public class WebSocketSessionStub implements WebSocketSession{

@Override
public String getId() {

    return "SESSION1";
}

@Override
public URI getUri() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public HttpHeaders getHandshakeHeaders() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public Map<String, Object> getAttributes() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public Principal getPrincipal() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public InetSocketAddress getLocalAddress() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public InetSocketAddress getRemoteAddress() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public String getAcceptedProtocol() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void setTextMessageSizeLimit(int messageSizeLimit) {
    // TODO Auto-generated method stub

}

@Override
public int getTextMessageSizeLimit() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public void setBinaryMessageSizeLimit(int messageSizeLimit) {
    // TODO Auto-generated method stub

}

@Override
public int getBinaryMessageSizeLimit() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public List<WebSocketExtension> getExtensions() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void sendMessage(WebSocketMessage<?> message) throws IOException {
    // TODO Auto-generated method stub

}

@Override
public boolean isOpen() {
    System.out.println("isOpen");
    return true;
}

@Override
public void close() throws IOException {
    // TODO Auto-generated method stub

}

@Override
public void close(CloseStatus status) throws IOException {
    // TODO Auto-generated method stub

   }

 }
@组件
公共类WebSocketSessionStub实现WebSocketSession{
@凌驾
公共字符串getId(){
返回“会话1”;
}
@凌驾
公共URI getUri(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共HttpHeaders getHandshakeHeaders(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共映射getAttributes(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共主体getPrincipal(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共InetSocketAddress getLocalAddress(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共InetSocketAddress getRemoteAddress(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
公共字符串getAcceptedProtocol(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
public void setTextMessageSizeLimit(int messageSizeLimit){
//TODO自动生成的方法存根
}
@凌驾
public int getTextMessageSizeLimit(){
//TODO自动生成的方法存根
返回0;
}
@凌驾
public void setBinaryMessageSizeLimit(int messageSizeLimit){
//TODO自动生成的方法存根
}
@凌驾
public int getBinaryMessageSizeLimit(){
//TODO自动生成的方法存根
返回0;
}
@凌驾
公共列表getExtensions(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
public void sendMessage(WebSocketMessage消息)引发IOException{
//TODO自动生成的方法存根
}
@凌驾
公共布尔等参元(){
System.out.println(“isOpen”);
返回true;
}
@凌驾
public void close()引发IOException{
//TODO自动生成的方法存根
}
@凌驾
公共作废关闭(关闭状态)引发IOException{
//TODO自动生成的方法存根
}
}
下面是我的单元测试课

@RunWith(SpringRunner.class)
@SpringBootTest
public class TextHandlerTest {

@Autowired
TextHandler textHandler;

@Mock
WebSocketSessionStub ws;

@Mock
WebSocketMessage<TextMessage> webSocketMessage;

TextMessage textMsg = new TextMessage("Test Message".getBytes());

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    textHandler.handleMessage(ws, textMsg);     
}


@Test
public void verifyCallToIsOpenConnection() throws Exception {

    verify(ws, times(1)).isOpen();
    System.out.println("isOpen " + ws.isOpen());

 }

}
@RunWith(SpringRunner.class)
@春靴测试
公共类TextHandlerTest{
@自动连线
文本处理程序文本处理程序;
@嘲弄
WebSocketSessionsTubWS;
@嘲弄
WebSocketMessage WebSocketMessage;
TextMessage textMsg=newtextmessage(“测试消息”.getBytes());
@以前
public void setUp()引发异常{
initMocks(this);
handleMessage(ws,textMsg);
}
@试验
public void verifyCallToIsOpenConnection()引发异常{
验证(ws,times(1)).isOpen();
System.out.println(“isOpen”+ws.isOpen());
}
}

上述测试通过,但
isOpen
计算结果为假。因此,我无法验证
sendMessage
方法调用。如何更正它?

您可以模拟
WebSocketSession
并将其注入
TextHandler\handleTextMessage

/*  
 *  You don't need spring context while mocking. 
 *  Hence No need to have spring runner. 
 */
@RunWith(MockitoJunitRunner.class)
public class TextHandlerTest {

    @Test
    public void verifyCallToIsOpenConnection() {
         WebSocketSession session = mock(WebSocketSession.class);
         TextMessage textMsg = new TextMessage("Test Message".getBytes());

         when(session.isOpen()).thenReturn(true);

         TextHandler textHandler = new TextHandler();

         // Pass the mocked session object here
         textHandler. handleTextMessage(session, textMsg);

         // Now you can verify if session.sendMessage() was called or not
         verify(session, times(1)).sendMessage(textMsg);
    }
}

如果使用Mockito,为什么要使用存根?另外,您只创建了一个模拟,没有为它注册任何行为。。。
boolean
的默认值是返回
false
。向Mockito注册正确的行为(如果不需要,请丢弃存根)。