【问题标题】:Mock a function from another file - Jest模拟另一个文件中的函数 - Jest
【发布时间】:2018-08-27 19:22:15
【问题描述】:

我正在为我的应用程序编写单元测试用例。有一个函数写在 Utils 部分并在所有文件中使用。我想在需要时模拟这个 Utils 函数,但我无法这样做。

这是我的代码设置:

Utils.js

> const getData = (name) => "Hello !!! " + name;
> 
> const getContact = ()=> return Contacts.mobile;
> 
> export {
>     getData,
>     getContact }

Login.js(使用 Utils.js)

    const welcomeMessage = (name) => {

    return getData(name);
    }

我的测试文件(Login.spec.js)

import { getData } from '../../src/utils';


jest.mock('getData', () => jest.fn())


describe('User actions', () => {

    it('should get username', () => {
        const value = 'Hello !!! Jest';
        expect(welcomeMessage('Jest')).toEqual(value);
    });

});

当我运行我的测试用例时,我收到了这个错误:

 Cannot find module 'getData' from 'Login.spec.js'

我试图在官方 Jest 文档和 SO 上找到解决方案,但找不到任何东西。我无法修复此错误并模拟此函数。

【问题讨论】:

    标签: javascript reactjs unit-testing jestjs


    【解决方案1】:

    jest.mock(...)的第一个参数必须是模块路径:

    jest.mock('../../src/utils');
    

    因为utils 模块是您的代码,而不是第三个库,所以您必须学习手动模拟玩笑: https://facebook.github.io/jest/docs/en/manual-mocks.html

    如果你有这个文件:src/utils.js

    你可以通过创建一个文件来模拟它:src/__mocks__/utils.js

    此文件的内容是对原始文件的复制,但将实现替换为getData = jest.fn()

    在您的测试文件上,只需在文件开头调用:jest.mock('../../src/utils');

    那么当你熟悉了,你可以在beforeEach()里面调用那个函数,然后调用它的计数器jest.unmock('../../src/utils');insiderafterEach()

    一种简单的思考方式是:

    当您致电jest.mock('../../src/utils'); 时,意味着您告诉jest

    嘿,如果运行测试遇到require('../../src/utils')这一行,不要加载它,让加载../../src/__mocks__/utils

    【讨论】:

    • 在那种情况下,开玩笑怎么知道我必须模拟 getData 因为它不是一个模块,它只是一个函数。
    • 如果你实现手动模拟,开玩笑只加载你的模拟模块,它只包含你所有功能的模拟实现
    • 您是否可以给我看一个例子,因为我是 Jest 的新手,这对我来说似乎有点困惑。 @Khoa
    • @Khoa 如果我想在我正在测试的同一个文件中模拟一个函数怎么办?
    • @David:我必须说我无法回答你的问题。这是因为我需要一个上下文。这意味着您必须像这个问题的作者一样向我提供一个具体的例子。单元测试不能应用于任何代码。这就是为什么人们说“编写可测试的代码”。
    【解决方案2】:

    我遇到了同样的问题,最后我找到了解决方案。我在这里发给遇到同样问题的人。

    Jest 测试文件:

    import * as utils from "./demo/utils";
    import { welcomeMessage } from "./demo/login";
    
    // option 1: mocked value
    const mockGetData = jest.spyOn(utils, "getData").mockReturnValue("hello");
    
    // option 2: mocked function
    const mockGetData = jest.spyOn(utils, "getData").mockImplementation((name) => "Hello !!! " + name);
    
    describe("User actions", () => {
        it("should get username", () => {
            const value = "Hello !!! Jest";
            expect(welcomeMessage("Jest")).toEqual(value);
        });
    });
    

    参考: https://jestjs.io/docs/jest-object#jestfnimplementation

    jest.spyOn(object, methodName)

    创建一个类似于 jest.fn 的模拟函数,但也跟踪对 对象[方法名]。返回一个 Jest 模拟函数。

    注意:默认情况下,jest.spyOn 也调用 spie 方法。这是与大多数其他测试库不同的行为。如果要覆盖原函数,可以使用:

    jest.spyOn(object, methodName).mockImplementation(() => customImplementation)
    

    object[methodName] = jest.fn(() => customImplementation);
    

    【讨论】:

      【解决方案3】:

      另一种解决方案会通过以下方式伪造这一点:

      window['getData'] = jest.fn();
      

      【讨论】:

        猜你喜欢
        • 2019-09-19
        • 2021-04-19
        • 1970-01-01
        • 2021-03-03
        • 2020-02-15
        • 1970-01-01
        • 2019-04-09
        • 1970-01-01
        • 2019-01-24
        相关资源
        最近更新 更多