Javascript 在Jest中重置节点模块
我有一个Node.js应用程序,Javascript 在Jest中重置节点模块,javascript,node.js,unit-testing,jestjs,Javascript,Node.js,Unit Testing,Jestjs,我有一个Node.js应用程序,index.js对类Unix和Windows平台有不同的导出 import os from "os"; function throwNotSupportedError() { throw new Error("Platform not supported."); } console.log(os.platform()); switch (os.platform()) { case "darwin": case "linux": modul
index.js
对类Unix和Windows平台有不同的导出
import os from "os";
function throwNotSupportedError() {
throw new Error("Platform not supported.");
}
console.log(os.platform());
switch (os.platform()) {
case "darwin":
case "linux":
module.exports = {
foo: require("./unix/foo"),
bar: require("./unix/bar")
};
break;
case "win32":
module.exports = {
foo: require("./win32/foo"),
bar: require("./win32/bar")
};
break;
default:
throwNotSupportedError();
}
我试图用单元测试来覆盖这个文件,如下所示:
import os from "os";
jest.mock("os");
describe("Linux platform", () => {
test("has `foo` and `bar` methods on Linux platform", () => {
os.platform.mockImplementation(() => "linux");
const app = require("../src");
expect(app.foo).toBeTruthy();
expect(app.bar).toBeTruthy();
});
});
describe("Windows platform", () => {
test("has `foo` and `bar` methods on Windows platform", () => {
os.platform.mockImplementation(() => "win32");
const app = require("../src");
expect(app.foo).toBeTruthy();
expect(app.bar).toBeTruthy();
});
});
问题是,os.platform.mockImplementation(()=>“win32”)代码>可以工作,但是console.log(os.platform())
仍然显示linux
,即使我在每个测试用例中导入应用程序const-app=require(../src”)代码>
我的错误在哪里?如何解决它?您在测试范围内模拟os
模块,但您的实际代码在自己的范围内使用该模块jest.mock
只接受导出的方法,并将它们替换为jest.fn
,因此,理论上,您的代码需要导出os
,然后您的测试代码应该只需要在文件顶部使用您的代码一次。测试代码不应直接导入操作系统
顺便说一句,这只是未经测试的理论。在每次测试后,您需要使用以下方法清除模块缓存:
describe("Windows platform", () => {
afterEach(() => {
jest.resetModules();
})
//...
})
康的回答指向了正确的方向。我想补充一点,当您重置模块时,对任何过去导入的引用都将被“忽略”(重置后将创建一个新实例)。换句话说,从“os”导入os模块重置后,将不再使用测试顶部的代码>
解决方案
除此之外,您还需要在即将执行的测试中重新导入(或在本例中重新要求)操作系统模块。通过这样做,os.platform.mockImplementation(()=>“win32”)代码>将应用于模块模拟的最新实例。您的两个测试都需要以这种方式构建
test("has `foo` and `bar` methods on Windows platform", () => {
const os = require('os');
os.platform.mockImplementation(() => "win32");
const app = require("./os-test");
expect(app.foo).toBeTruthy();
expect(app.bar).toBeTruthy();
});
您可能希望在每次
之前使用,而不是每次
之后使用,以确保测试前操作系统
模块清洁。Jest应该隔离每个测试文件,但安全性比抱歉好?最后,您希望在所有测试之前运行beforeach
,而不仅仅是在“Windows平台”中description
。为此,您可以将其移动到文件的根目录,或将这两个描述
包装到另一个描述
,例如
jest.mock("os");
describe('Platform specific module', () => {
beforeEach(() => {
jest.resetModules();
});
describe("Linux platform", () => {
test("has `foo` and `bar` methods on Linux platform", () => {
const os = require('os');
os.platform.mockImplementation(() => "linux");
...
我希望这有帮助!嘲弄往往很棘手,而不仅仅是开玩笑
参考资料