繁体   English   中英

在 Jest 中模拟出口

[英]Mocking exported exports in Jest

我有一个问题,如果我export * from submodule (使用 ES6 模块语法和 babel),我无法从入口点使用Jest mock子模块函数。 我想知道有没有人可以帮忙...

例如给出这个结构:

+ __tests__
|    |- index.js
+ greeter
|    |- index.js
|    |- submodule.js
|- index.js

而这段代码:

index.js

import { sayHello } from "./greeter";

export const greet = (name) => sayHello(name);

greeter/index.js

export * from "./submodule.js";

greeter/submodule.js

export const sayHello = (name) => console.log(`Hello, ${name}`);

__tests__/index.js

import { greet } from "../index";
import * as greeter from "../greeter";

describe("greet", () => {
    it("Should delegate the call to greeter.sayHello", () => {
        const name = "John";

        greet(name);
    });
});

这一切正常,当测试运行时它通过了。 Hello, John按预期打印到控制台。 对我来说值得的优点是index.js完全不知道greeter模块的结构,所以我可以重构和重构该代码而不必担心我的消费者。

当我尝试模拟greeter.sayHello,摩擦就来了……

__tests__/index.js

import { greet } from "../index.js";
import * as greeter from "../greeter";

greeter.sayHello = jest.fn();

describe("greet", () => {
    it("Should delegate the call to greeter.sayHello", () => {
        const name = "John";

        greet(name);

        expect(greeter.sayHello).toHaveBeenCalledWith(name);
    });
});

现在,而不是按预期通过测试 - 我收到一个错误:

Test suite failed to run

TypeError: Cannot set property sayHello of [object Object] which only has a getter
...(stack trace)

__tests__/index.js中的__tests__/index.jsimport更改为:

import * as greeter from "../greeter/submodule";

使测试通过,但将耦合放回我的测试代码中。

还有其他方法吗?

为了在要测试的文件上模拟导入的方法,您需要确保在导入文件(index.js)之前模拟已运行,如下所示:

// import { greet } from "../index.js";   =====> Import on each test case(it)
// import * as greeter from "../greeter"; =====> Mock on each test case(it)

// greeter.sayHello = jest.fn(); =====> Would be not good to do this, it will mess with the entire import and this jest.fn will be share across your tests making it gives you false positives.

describe("greet", () => {
    it("Should delegate the call to greeter.sayHello", () => {
        const name = "John";

        jest.mock('../greeter', () => ({ sayHello: jest.fn() })); // here you mock the import, remember it needs to be before you require your index.js

        const greet = require('../index.js').greet; // require after the mock

        greet(name);

        expect(greeter.sayHello).toHaveBeenCalledWith(name);
    });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM