如何在JavaScript中使用Math.random进行测试?

时间:2012-05-09 11:16:21

标签: javascript unit-testing

我有一个函数可以选择最小值和最大值之间的随机值。因此,当我进行测试时,我测试该值落在最小值和最大值之间。但是由于我的应用程序中出现了一些失败,测试通过了一些时间,有些时候由于随机性而失败。

覆盖/模拟Math.random()以返回0和1并测试我的值是否与最大值或最小值相同是不是一个好主意?或者有更好的方法来测试JavaScript中的随机性吗?

以下是用于创建随机数的函数:

function constrain(min, max){
    return Math.round(Math.random() * (max - min) + min)
}

3 个答案:

答案 0 :(得分:17)

SinonJS是一个JavaScript mocking framework,它集成了所有主要的JavaScript单元测试框架。适配器将负责“恢复”您在测试期间创建的任何存根/模拟。

// Stub out Math.random so it always returns '4' (chosen by fair dice roll)
sinon.stub(Math, 'random').returns(4);

// Double check that it worked.
equal(Math.random(), 4, "http://xkcd.com/221/");

答案 1 :(得分:2)

优选地,您的测试中应该没有random元素。您应该提供方法已知值,以便确定结果是否与您所感知的完全一致。

如果你有随机值,你必须经常测试这个方法,而你仍然不确定你得到了你想要的确切结果,只是你得到的东西在正确的范围内。

例如,如果您在代码中使用当前日期(new Date()),那么您应该在测试时为您的方法提供已知日期,否则您的测试只会显示该方法现在正常工作。明天它可能会失败。


编辑:

但是,我可以马上告诉你,你的方法效果不好。您应该使用floor方法而不是round,否则最低和最高值的出现频率是其他值的一半:

function constrain(min, max){
  return Math.floor(Math.random() * (max - min + 1) + min)
}

答案 2 :(得分:1)

通常,您的测试应该传递非确定性代码的所有可能值。也许你的测试中有一个循环,你做了100次测试。这将在不更改应用程序代码的情况下捕获更多故障您的建议也是一种选择。