首页 > 解决方案 > 当源代码更改时,带有种子随机数的玩笑测试是不可预测的,并且测试失败

问题描述

我在这里创建了一个小的可重现测试用例:https ://github.com/opyate/jest-seedrandom-testcase

当我使用seedrandom时,我得到了可预测的随机性,正如测试所证明的那样(使用 一次又一次地运行它时npx jest)。

但是,当我在测试中添加无关紧要的代码时,它会失败。

谁能阐明为什么会发生这种情况?更重要的是,如何配置jest以便测试在更改时不会失败?

标签: node.jstypescriptrandomjestjs

解决方案


我已经在https://github.com/opyate/jest-seedrandom-testcase更新了 repo,并给出了解释:

全局修补Math.random不是正确的方法,因为 Node/Jest 内部可能会调用Math.random并推进 RNG。

这可以通过取消注释为测试增加另一个期望的行来证明,因为它将 RNG 又推进了 9 次。

遗憾的是,被测代码不适合模拟/注入,但在正常情况下,建议Math.random像这样模拟:

import seedrandom from "seedrandom"
import { expect, test, jest } from "@jest/globals"

beforeEach(() => {
    const rng = seedrandom("hello.")
    jest.spyOn(global.Math, 'random').mockImplementation(rng)
})

afterEach(() => {
    jest.spyOn(global.Math, 'random').mockRestore()
})

推荐阅读