如何使用 Jest 和 React-testing-library 测试 Websocket 客户端

问题描述 投票:0回答:2

我使用create-react-app、Jest 和react-testing-library 来配置聊天机器人项目。

例如,我有一个连接到 WebSocket 服务器的 React 功能组件,并且 DOM 根据 WebSocket 消息进行更改

const LiveChat = () => {
  const [socket, setSocket] = useState(null)

   useEffect(() => {
    setSocket(new WebSocket('ws://localhost:1234'))
   }, [])

  useEffect(() => {
    socket && socket.onmessage = message => { handleAgentMessages(message.data) }
  }, [socket])

  const handleAgentMessages = message => {
     const { messageContent, messageType, secureKey } = JSON.parse(message)
     if (messageType === TEXT && messageContent) {
       alert(messageContent)
       playChatMessageSound()
     }
       ...
   }

   return (
      <div className='live-chat' data-testid='live-chat'>
          ...
      </div>
   )
}

我想测试当文本消息到来时,警报框是否出现并包含消息等。我浏览了互联网,找到了 jest-websocket-mock 库,但似乎我需要用这个库来模拟客户端同样,但我只想模拟服务器并期望客户端连接模拟的 WebSocket 服务器,你有什么想法吗?

reactjs websocket mocking jestjs react-testing-library
2个回答
3
投票

我不确定这是否正确。但这对我有用,

    global.sendMsg = null;
    global.WebSocket = class extends WebSocket {
        constructor(url) {
            super("wss://test");
            global.sendMsg = null
        }
    
        addEventListener(event, cb) {
            if (event === "open") {
                cb();
            } else if(event === "message") {
                global.sendMsg = cb;
            }
        }
    };

    test("testing message",() => {
      render(<LiveChat />);
      global.sendMsg({data:"test-msg"});
 
      expect....
    })

基本上,我重写了 WebSocket 类并将消息事件回调存储到一个常量中,并在测试中触发它以模仿服务器消息。


0
投票

另一种方法是将 Web 套接字服务器注入自定义 Jest 环境中。由于

Websocket is not a constructor
错误,我不得不这样做。

在你的 jest.config.js 文件中

...
  testEnvironment: "./custom-dom-environment.",
...

自定义-dom-environment.js

// my-custom-environment
const JsDomEnvironment = require('jest-environment-jsdom').TestEnvironment;

class CustomEnvironment extends JsDomEnvironment {
  constructor(config, context) {
    super(config, context);

  }

  async setup() {
    await super.setup();
    // Allow setting up a websocket server in jsdom environment
    this.global.WebSocketServer = require('ws');
  }

  async teardown() {
    await super.teardown();
  }

  getVmContext() {
    return super.getVmContext();
  }
}

module.exports = CustomEnvironment;

© www.soinside.com 2019 - 2024. All rights reserved.