我在TypeScript环境中关注this guide。我的目的是模拟测试中的socket.io-client
实现,以便可以在即时消息传递组件中模拟套接字事件。
// __mocks__/socket.io-client.js
// SOURCE: https://medium.com/free-code-camp/testing-socket-io-client-app-using-jest-and-react-testing-library-9cae93c070a3
let EVENTS = {};
function emit(event, ...args) {
EVENTS[event].forEach(func => func(...args));
}
const socket = {
on(event, func) {
if (EVENTS[event]) {
return EVENTS[event].push(func);
}
EVENTS[event] = [func];
},
emit,
};
export const io = {
connect() {
return socket;
},
};
// Additional helpers, not included in the real socket.io-client,just for out test.
// to emulate server emit.
export const serverSocket = { emit };
// cleanup helper
export function cleanup() {
EVENTS = {};
}
export default io;
我的代码中有一个套接字包装,其中包含一些便捷方法,其中包括以下片段:
// SocketWrapper.ts
import * as io from 'socket.io-client';
/* Code removed for brevity */
console.log(io);
console.log(JSON.stringify(io));
this.socket = io.connect(
运行测试时,出现以下错误:
FAIL src/components/User/components/Messages/Messages.test.tsx
● Test suite failed to run
TypeError: io.connect is not a function
55 | console.log(JSON.stringify(io));
56 |
> 57 | this.socket = io.connect(
at MessagesService.connect (src/lib/classes/SocketWrapper.ts:69:19)
at MessagesService.connect (src/services/Messages.service.ts:29:11)
at new MessagesService (src/services/Messages.service.ts:25:10)
at Object.<anonymous> (src/components/User/components/Messages/Messages.tsx:9:17)
at Object.<anonymous> (src/components/User/User.tsx:3:1)
at Object.<anonymous> (src/testUtils/pages/UserPage.tsx:10:1)
at Object.<anonymous> (src/components/User/components/Messages/Messages.test.tsx:2:1)
console.log src/lib/classes/SocketWrapper.ts:54
{ cleanup: [Function: cleanup],
io: { connect: [Function: connect] },
serverSocket: { emit: [Function: emit] },
default: { connect: [Function: connect] } }
console.log src/lib/classes/SocketWrapper.ts:55
{"io":{},"serverSocket":{},"default":{}}
正如我在以字符串形式记录模块时在日志中看到的那样,该模拟返回空对象,而不是模拟的实现。我到处都看过,但似乎找不到解决方案。
答案 0 :(得分:0)
来自此文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
name参数是“模块对象”的名称,它将用作引用导出的一种名称空间。导出参数指定单个命名的导出,而import * as name语法将导入所有这些导出。
这意味着如果使用import * as io from 'socket.io-client'
,则io
是一种名称空间。
在模拟文件中,io
是一个对象,export default io;
如果您使用import * as io from 'socket.io-client'
。 io
变量的值为:
{ // <- the outer object is io namespace
io: { // <- this is the io object you defined in your mock file
connect() {
return socket;
}
}
}
使用import io from 'socket.io-client'
,它将从中导入默认对象:
const io = {
connect() {
return socket;
},
};
如果您坚持使用import * as io from 'socket.io-client'
语句。
更改
export const io = {
connect() {
return socket;
},
};
收件人:
export function connect() {
return socket;
}
并删除export default io;
语句。