首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jest中的Reseting节点模块

Jest中的Reseting节点模块
EN

Stack Overflow用户
提问于 2019-07-07 10:25:18
回答 3查看 2.5K关注 0票数 2

我有一个Node.js应用程序,index.js对类似Unix的平台和Windows平台有不同的导出。

代码语言:javascript
复制
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();
}

我试图用如下所示的单元测试来覆盖这个文件:

代码语言:javascript
复制
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");中导入应用程序。

我的错误在哪里,如何解决?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-07-13 12:00:02

张先生对jest.resetModules()的回答是指向正确的方向。我想补充的是,当您重置模块时,对任何过去导入的引用将被“忽略”(重置后将创建一个新实例)。换句话说,测试顶部的import os from "os";将在模块重置后不再使用。

溶液

除了jest.resetModules()之外,您还需要在将要执行的测试中重新导入(或者在本例中是重新要求) os模块。通过这样做,os.platform.mockImplementation(() => "win32");将应用于模块模拟的最新实例。你的两个测试都需要这样的结构;

代码语言:javascript
复制
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();
});

您可能希望使用beforeEach而不是afterEach,以确保在测试之前os模块是干净的。Jest应该隔离每个测试文件,但是安全比抱歉好吗?最后,您希望在所有测试之前运行beforeEach,而不仅仅是在"Windows“describe中运行。要做到这一点,您可以将其移动到文件的根目录,也可以将两个describe封装在一个附加的describe中,例如。

代码语言:javascript
复制
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");
      ...

我希望这能帮到你!嘲笑往往是很棘手的,而不仅仅是在Jest。

参考资料

票数 3
EN

Stack Overflow用户

发布于 2019-07-09 19:48:57

您正在测试范围内模拟os模块,但实际代码在它自己的范围内使用该模块。jest.mock只使用导出的方法并将它们替换为jest.fn,所以理论上,您的代码需要导出os,然后测试代码应该只需要在文件顶部一次。您的测试代码不应该直接导入os

顺便说一句,这只是一个未经检验的理论,从阅读关于Jest模拟的教程

票数 0
EN

Stack Overflow用户

发布于 2019-07-10 09:22:41

您需要在每次测试之后使用jest.resetModules()来清除模块缓存:

代码语言:javascript
复制
describe("Windows platform", () => {
    afterEach(() => {
        jest.resetModules();
    })

    //...
})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56921304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档