首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仅在函数数组上使用Jest模拟一个函数

仅在函数数组上使用Jest模拟一个函数
EN

Stack Overflow用户
提问于 2021-06-30 11:16:13
回答 1查看 3.7K关注 0票数 3

这是我的功能

代码语言:javascript
复制
//functions.js
const functions =
{
    add: (a, b) => a + b,
    average: (a, b) => functions.add(a, b) / 2
}


module.exports = functions;

我的测试开始了,

代码语言:javascript
复制
jest.mock("./functions"); // this happens automatically with automocking

const functions = require("./functions");

test('calculate the average', () => {

    functions.add.mockImplementation((a, b) => a + b);
    expect(functions.average(2, 2)).toBe(2);

})

我知道如何在NestJS上这样做,至少在我所处的环境中是这样的。我正在准备一个Udemy教程,我想做一个简单的例子。我希望能够再次检查方法add是否被正确调用,参数是否被正确调用。

问题是,自动锁定是在嘲弄一切。我只想模拟add函数,因为我知道发生了什么。

我找到了这个解决方案,但当我试图改变Jest的理论时,我觉得缺少了一些东西。

代码语言:javascript
复制
//jest.mock("./functions"); // this happens automatically with automocking

const functions = require("./functions");

test('calculate the average', () => {

    const spy = jest.spyOn(functions, 'add').mockImplementation((a, b) => console.log("I was called"));
    //functions.add.mockImplementation((a, b) => a + b);
    functions.average(2, 2)
    //expect(functions.average(2, 2)).toBe(2);
    expect(spy.mock.calls[0][1]).toBe(2);
})

试图实现一个拟议的解决方案,这是有意义的,然而,它并不像我预期的那样工作。我无法访问模拟属性。这个想法是,信息应该被存储,就像传统的模拟一样,但是,我如何访问呢?

代码语言:javascript
复制
jest.mock('./functions', () => {
    // Require the original module to not be mocked...
    const originalModule = jest.requireActual('./functions');

    return {
        __esModule: true, // Use it when dealing with esModules
        ...originalModule,
        add: jest.fn((a, b) => a + b),
    };
});

const functions = require("./functions");

test('calculate the average', () => {

    const add = require("./functions").add;

    functions.average(2, 2);
    expect(add.mock.calls[0][1]).toBe(2);

})

也曾尝试:

代码语言:javascript
复制
test('calculate the average', () => {

    const add = require("./functions").add;
    expect(functions.average(2, 2)).toBe(2);
})

这显示了模拟是“本地的”,即使在模仿之后,average也在调用正常的方法,在间谍的情况下,它调用被模仿的方法。看来唯一的解决办法就是间谍的善后。

我更改了模拟函数,以证明调用了哪个函数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-03 08:07:28

试试这样的东西。这只会模拟add函数。

代码语言:javascript
复制
jest.mock("./functions", () => ({
    ...jest.requireActual("./functions"),
    add: jest.fn(() => {}) // Pass your mock implementation as param in jest.fn() 
}));

const functions = require("./functions");

更新

如果您想要使用实际的函数以及

代码语言:javascript
复制
describe("Mocking dependent functions", () => {
    afterEach(() => {
        jest.resetModules()
    });

    it('average should be 400', () => {
        const functions = jest.requireActual('./function');
        functions.add = jest.fn(() => 800); // using mock
        expect(functions.average(2, 2)).toBe(400);
    });
    
    it('average should be 2', () => {
        const functions = jest.requireActual('./function'); // using actual function
        expect(functions.average(2, 2)).toBe(2);
    });

    it('average should be 5', () => {
        const functions = jest.requireActual('./function');
        functions.add = jest.fn(() => 10); // using mock
        expect(functions.average(2, 2)).toBe(5);
    });
});

如果只想使用模拟函数,则为

代码语言:javascript
复制
const functions = jest.requireActual('./function');
describe("Mocking dependent functions", () => {
    it('average should be 400', () => {
        functions.add = jest.fn(() => 800); // using mock
        expect(functions.average(2, 2)).toBe(400);
    });

    it('average should be 5', () => {
        functions.add = jest.fn(() => 10); // using mock
        expect(functions.average(2, 2)).toBe(5);
    });
})

在第一种方法中,您可能也想使用实际的函数,Jest无法清除模拟,也就是说,为什么我必须在每个测试用例中要求函数文件,而在每个测试用例之后,我必须重置模块.。

有另一种解决这个问题的方法,但我不喜欢这样。仍在添加代码供您参考。在这里,您可以保留原始函数的副本,以便稍后引用它()

代码语言:javascript
复制
const functions = jest.requireActual('./function');
const originalFunctions = { ...functions };

describe("Mocking dependent functions", () => {
    it('average should be 400', () => {
        functions.add = jest.fn(() => 800); // using mock
        expect(functions.average(2, 2)).toBe(400);
    });
    
    it('average should be 2', () => {
        functions.add = originalFunctions.add; // getting actual function from copy
        expect(functions.average(2, 2)).toBe(2);
    });
});

记住:当您调用require()时,您将得到一个带有对模块函数的引用的对象。因此,当您重写函数时,始终尝试恢复原始状态。因此,推荐使用jest.resetModule()方法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68193736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档