我是writing a Bluetooth library,我正在用Jest测试它。对于我的测试,我正在进行实际的无线电通信,以确保一切均正常运行。但是,此类测试无法在CI系统上运行。因此,对于我的CI系统(仅限我的CI系统),我想使用模拟。对于本地开发,我不想模拟任何东西。
所以我试图有条件地嘲笑一个模块:
import MyModule from "./myModule";
if (true) {
jest.mock("./myModule");
}
describe("MyModule", () => {
let myModule;
beforeEach(() => {
myModule = new MyModule();
});
test("I am NOT mocked", () => {
expect(myModule.powerOn()).toBe("I am the original implementation");
});
test("I am mocked", () => {
if (myModule.powerOn.mockReturnValueOnce)
myModule.powerOn.mockReturnValueOnce("I am a mock");
expect(myModule.powerOn()).toBe("I am a mock");
});
});
但这不起作用。我的测试结果是
FAIL ./index.test.js MyModule ✓ I am NOT mocked (3ms) ✕ I am mocked (6ms) ● MyModule › I am mocked expect(received).toBe(expected) // Object.is equality Expected: "I am a mock" Received: "I am the original implementation" 19 | if (myModule.powerOn.mockReturnValueOnce) 20 | myModule.powerOn.mockReturnValueOnce("I am a mock"); > 21 | expect(myModule.powerOn()).toBe("I am a mock"); | ^ 22 | }); 23 | }); 24 | at Object.toBe (index.test.js:21:32) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 passed, 2 total Snapshots: 0 total
一旦我删除了if子句
if (true) {
jest.mock("./myModule");
}
到
jest.mock("./myModule");
它按预期工作。
您可以在这里尝试
https://github.com/LukasBombach/jest-conditionally-mock-module-example
我无法将其放在CodeSanbox中,因为此代码会破坏它。
我读到,开玩笑需要在文件的根范围内进行模块模拟,因为它在运行文件并对文件进行魔术之前对其进行了解析。 我知道。
但是由于似乎不可能将jest.mock
放在if子句中,我还有其他方法可以使CI使用模拟并在本地实现实际实现吗?
答案 0 :(得分:0)
好的,我自己找到了解决方案。有a related question to this here,但我发现了另一个我更喜欢的解决方案。您可以使用第二个参数(工厂)来决定要返回模拟还是实际的模块
亲自看看
import MyModule from "./myModule";
jest.mock("./myModule", () => {
if (false) return jest.requireActual("./myModule");
return jest.genMockFromModule("./myModule");
});
describe("MyModule", () => {
const myModule = new MyModule();
test("I am the original", () => {
expect(myModule.powerOn()).toBe("I am the original implementation");
});
test("I am mocked", () => {
myModule.powerOn.mockReturnValueOnce("I am a mock");
expect(myModule.powerOn()).toBe("I am a mock");
});
});