简体   繁体   English

在 Jest 中模拟出口

[英]Mocking exported exports in Jest

I am having a problem whereby if I export * from submodule (using ES6 module syntax and babel) I am unable to mock the submodules functions using Jest from the entry point.我有一个问题,如果我export * from submodule (使用 ES6 模块语法和 babel),我无法从入口点使用Jest mock子模块函数。 I wondered if anyone out there could help...我想知道有没有人可以帮忙...

For example given this structure:例如给出这个结构:

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

And this code:而这段代码:

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);
    });
});

This all works fine and when the test runs it passes.这一切正常,当测试运行时它通过了。 Hello, John is printed to the console as expected. Hello, John按预期打印到控制台。 The advantage that make this worth it to me is that index.js is completely unaware of the structure of the greeter module, so i can restructure and refactor that code without worrying about my consumers.对我来说值得的优点是index.js完全不知道greeter模块的结构,所以我可以重构和重构该代码而不必担心我的消费者。

The Rub comes when I try and mock out greeter.sayHello ...当我尝试模拟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);
    });
});

Now instead of the test passing as expected - I get an error:现在,而不是按预期通过测试 - 我收到一个错误:

Test suite failed to run

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

Changing the greeter import in __tests__/index.js to:__tests__/index.js中的__tests__/index.jsimport更改为:

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

Makes the test pass but puts the coupling back in my test code.使测试通过,但将耦合放回我的测试代码中。

Is there another way?还有其他方法吗?

In order to mock a imported method on the file you want to test you need make sure the mock ran before you import your file(index.js), like this:为了在要测试的文件上模拟导入的方法,您需要确保在导入文件(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