模拟的npm模块以开玩笑的方式返回空对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟的npm模块以开玩笑的方式返回空对象相关的知识,希望对你有一定的参考价值。

我在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":{}}

正如您在将模块作为字符串记录时在日志中看到的那样,该模拟返回空对象,而不是模拟的实现。我到处都看过,但似乎找不到解决方案。

答案

来自此文档: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变量的值为:

{
  io: {
    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;语句。

以上是关于模拟的npm模块以开玩笑的方式返回空对象的主要内容,如果未能解决你的问题,请参考以下文章

在开玩笑的模拟模块工厂中模拟一个承诺

开玩笑的打字稿 - 模拟日期构造函数

Fragment 的 GetTag 返回空对象引用

Android Java:在 onCreateView() 中返回空视图的片段

如何以漂亮的方式记录 npm 模块的所有属性?

开玩笑模拟第三方对象