【问题标题】:How to test with Math.random in JavaScript?如何在 JavaScript 中使用 Math.random 进行测试?
【发布时间】:2012-05-09 11:16:20
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我不明白倒数第二句话...让Math.random() 返回01 有什么帮助?我认为您应该提供更多信息、示例和代码。也许你的测试有缺陷。
  • 我添加功能。传递 0/1 将返回我传递的最小值或最大值,因为这是 Math.random() 将返回的最小值/最大值。所以在我的测试中,而不是测试返回的值在最小值和最大值之间,我可以检查它是否等于最小值或最大值。

标签: javascript unit-testing


【解决方案1】:

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/");

【讨论】:

  • 顺便说一句。 Math.random 只返回 0 到 1 之间的值,所以 4 没有多大意义。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    最好在测试中完全没有random 元素。您应该为您的方法提供已知值,以便您可以确定结果是否正是您所期望的。

    如果您有随机值,您将不得不多次测试该方法,但您仍然不能确定您是否得到了您想要的确切结果,只能确定您得到的结果在正确的范围内。

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


    编辑:

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

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

    【讨论】:

    • 这就是我想模拟 math.random 的原因。
    • @AndreasKöberle:是的,在 Javascript 中你可以做到这一点。另一种选择是将随机函数分配给变量,即var getRandom = Math.random; 并在您的 ocde 中使用它,然后您可以更改变量的值而不是内置属性。
    猜你喜欢
    • 2015-11-02
    • 2014-04-04
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    相关资源
    最近更新 更多