Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Jest中重置节点模块_Javascript_Node.js_Unit Testing_Jestjs - Fatal编程技术网

Javascript 在Jest中重置节点模块

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

我有一个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":
    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");
      ...
我希望这有帮助!嘲弄往往很棘手,而不仅仅是开玩笑

参考资料