相同的随机数ruby

Gus*_*avo 1 ruby random

嗯,我是一个红宝石新手,我试图用RubyKoans学习,但我对这个测试感到困惑

def test_dice_values_should_change_between_rolls
 48     dice = DiceSet.new
 49     dice.roll(5)
 50     first_time = dice.values
 51    
 52     dice.roll(5)
 53     second_time = dice.values
 54     
 55     assert_not_equal first_time, second_time,
 56       "Two rolls should not be equal"
 57   end
Run Code Online (Sandbox Code Playgroud)

这是DiceSet类

5  class DiceSet
  6    attr_accessor :values
  7 ··
  8    def initialize
  9      @values = []
 10    end
 11 
 12    def roll(times)
 13      @values.clear
 14      times.times do |x|
 15        @values << ( 1 + rand(6))
 16      end
 17     end
 18 ····
 19    end
Run Code Online (Sandbox Code Playgroud)

这里的事情是,每当我运行代码时,它总是生成完全相同的数字集,这就是输出.

Two rolls should not be equal.  <[3, 2, 4, 1, 3]> expected to be != to  <[3, 2, 4, 1, 3]>.
Run Code Online (Sandbox Code Playgroud)

在测试我调用DiceSet.roll两次,对于那两次,我得到完全相同的"随机"数字,当他们被认为是不同的权利?我想我可能会创建另一个DiceSet实例以通过测试,但我猜测这不是测试的目标

Dom*_*nef 6

问题是DiceSet#values返回对数组的引用,并且该数组在DiceSet对象的整个生命周期内保持不变.在DiceSet#roll清除该数组然后添加新数字.由于两次调用都DiceSet#values返回相同的引用,因此第一次滚动的结果将丢失,并且您的测试是将数组与其自身进行比较.

我不熟悉RubyKoans以及它们有什么要求,即如果DiceSet应该存储值等等.如果是,那么最直接的解决方案是使用两个DiceSets或用于Object#dup存储返回对象的副本为了测试.

但请注意,即使代码运行正常,您的测试仍然很脆弱,因为总是有两次连续滚动返回完全相同的数字.在这种特殊情况下,它相对较小但仍然非常存在.

  • 劳驾?数字存储在`@ values`中,他使用属性读取器`#values`来获取该数组.`first_time`和`second_time`指向**完全相同的**数组. (2认同)