gpt4 book ai didi

javascript - 使用 Jest 模拟 Es6 类

转载 作者:IT老高 更新时间:2023-10-28 23:00:03 24 4
gpt4 key购买 nike

我正在尝试使用接收参数的构造函数来模拟 ES6 类,然后使用 Jest 在该类上模拟不同的类函数以继续测试。

问题是我找不到任何有关如何解决此问题的文档。我已经看过this post ,但它并没有解决我的问题,因为 OP 实际上甚至不需要模拟类(class)!该帖子中的另一个答案也根本没有详细说明,没有指向任何在线文档,也不会导致可复制的知识,因为它只是一段代码。

假设我有以下类(class):

//socket.js;

module.exports = class Socket extends EventEmitter {

constructor(id, password) {
super();

this.id = id;
this.password = password;

this.state = constants.socket.INITIALIZING;
}

connect() {
// Well this connects and so on...
}

};

//__tests__/socket.js

jest.mock('./../socket');
const Socket = require('./../socket');
const socket = new Socket(1, 'password');

expect(Socket).toHaveBeenCalledTimes(1);

socket.connect()
expect(Socket.mock.calls[0][1]).toBe(1);
expect(Socket.mock.calls[0][2]).toBe('password');

很明显,我试图模拟 Socket 和类函数 connect 的方式是错误的,但我找不到正确的方法所以。

请在你的回答中解释你模拟这个的逻辑步骤以及为什么每个步骤都是必要的 + 如果可能的话,提供指向 Jest 官方文档的外部链接!

感谢您的帮助!

最佳答案

更新:

所有这些信息和更多信息现在都已添加到新指南“ES6 Class Mocks”中的 Jest 文档中。

完全披露:我写的。 :-)


模拟 ES6 类的关键是知道ES6 类是一个函数。因此,mock 也必须是一个函数

  1. 调用jest.mock('./mocked-class.js');,同时导入'./mocked-class.js'。
  2. 对于要跟踪调用的任何类方法,创建一个指向模拟函数的变量,如下所示:const mockedMethod = jest.fn();。在下一步中使用它们。
  3. 调用 MockedClass.mockImplementation()。传入一个箭头函数,该函数返回一个包含任何模拟方法的对象,每个方法都设置为自己的模拟函数(在第 2 步中创建)。
  4. 可以使用手动模拟(__mocks__ 文件夹)模拟 ES6 类来完成相同的操作。在这种情况下,导出的模拟是通过调用 jest.fn().mockImplementation() 来创建的,参数与上面 (3) 中描述的参数相同。这将创建一个模拟函数。在这种情况下,您还需要导出任何要监视的模拟方法。
  5. 同样的事情可以通过调用 jest.mock('mocked-class.js', factoryFunction) 来完成,其中 factoryFunction 与上面 3 和 4 中传递的参数相同。

一个例子值一千字,所以这里是代码。此外,这里有一个 repo 演示了所有这些: https://github.com/jonathan-stone/jest-es6-classes-demo/tree/mocks-working

首先,对于您的代码

如果您要添加以下设置代码,您的测试应该会通过:

const connectMock = jest.fn(); // Lets you check if `connect()` was called, if you want

Socket.mockImplementation(() => {
return {
connect: connectMock
};
});

(注意,在您的代码中:Socket.mock.calls[0][1] 应该是 [0][0][0 ][2] 应该是 [0][1]。)

接下来,一个人为的例子

内嵌一些解释。

mocked-class.js。请注意,此代码在测试期间永远不会被调用。

export default class MockedClass {
constructor() {
console.log('Constructed');
}

mockedMethod() {
console.log('Called mockedMethod');
}
}

mocked-class-consumer.js。此类使用模拟类创建一个对象。我们希望它创建一个模拟版本而不是真实版本。

import MockedClass from './mocked-class';

export default class MockedClassConsumer {
constructor() {
this.mockedClassInstance = new MockedClass('yo');
this.mockedClassInstance.mockedMethod('bro');
}
}

mocked-class-consumer.test.js - 测试:

import MockedClassConsumer from './mocked-class-consumer';
import MockedClass from './mocked-class';

jest.mock('./mocked-class'); // Mocks the function that creates the class; replaces it with a function that returns undefined.

// console.log(MockedClass()); // logs 'undefined'

let mockedClassConsumer;
const mockedMethodImpl = jest.fn();

beforeAll(() => {
MockedClass.mockImplementation(() => {
// Replace the class-creation method with this mock version.
return {
mockedMethod: mockedMethodImpl // Populate the method with a reference to a mock created with jest.fn().
};
});
});

beforeEach(() => {
MockedClass.mockClear();
mockedMethodImpl.mockClear();
});

it('The MockedClassConsumer instance can be created', () => {
const mockedClassConsumer = new MockedClassConsumer();
// console.log(MockedClass()); // logs a jest-created object with a mockedMethod: property, because the mockImplementation has been set now.
expect(mockedClassConsumer).toBeTruthy();
});

it('We can check if the consumer called the class constructor', () => {
expect(MockedClass).not.toHaveBeenCalled(); // Ensure our mockClear() is clearing out previous calls to the constructor
const mockedClassConsumer = new MockedClassConsumer();
expect(MockedClass).toHaveBeenCalled(); // Constructor has been called
expect(MockedClass.mock.calls[0][0]).toEqual('yo'); // ... with the string 'yo'
});

it('We can check if the consumer called a method on the class instance', () => {
const mockedClassConsumer = new MockedClassConsumer();
expect(mockedMethodImpl).toHaveBeenCalledWith('bro');
// Checking for method call using the stored reference to the mock function
// It would be nice if there were a way to do this directly from MockedClass.mock
});

关于javascript - 使用 Jest 模拟 Es6 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47410939/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com