用 Jest 模拟 JavaScript Math.random 不起作用

Mocking JavaScript Math.random with Jest doesn't work

Math.random() 总是给出随机值而不是模拟值。

index.test.js

jest.spyOn(global.Math, "random").mockReturnValue(0.123456789);

const html = fs.readFileSync(path.resolve(__dirname, "./index.html"), "utf8");

let dom;
let container;

describe("index.html", () => {
  beforeEach(() => {
    dom = new JSDOM(html, { runScripts: "dangerously" });
    container = dom.window.document.body;
  });

  it("renders body paragraph", () => {
    expect(container.querySelector("p")).toBeInTheDocument();
  });
});

index.html

<html lang="en">
  <body>
    <p>title</p>
    <script>
      // not showing mocked value
      console.log(Math.random())
    </script>
  </body>
</html>

是否有可能在加载时创建一个新实例,因此不选择模拟?足够有趣的嘲讽 setInterval 有效。

也试过.mockImplementation(() => 0.123456789)没用。

它看起来不像是 JSDOM 的模拟。为了解决这个问题,我个人建议将脚本拆分到它自己的文件中,然后 运行 对脚本文件进行测试,如下例所示。将它们分开后,只需将脚本文件包含在 HTML 文件中即可。

script.js

Math.random();

script.spec.js

describe("script.js", () => {
    let spyOnMathRandom;

    beforeEach(() => {
        spyOnMathRandom = jest.spyOn(global.Math, 'random').mockReturnValue(1);
        require('./script');
    });

    it("calls math random", () => {
        expect(spyOnMathRandom).toReturnWith(1);
    });
});

index.html

<html lang="en">
<body>
<p>title</p>
<script src="script.js"></script>
</body>
</html>