在测试"无限循环"时,最佳做法是什么?

mar*_*cgg 24 ruby tdd rspec ruby-on-rails rr

我的基本逻辑是在某个地方运行无限循环并尽可能地测试它.拥有无限循环的原因并不重要(游戏的主循环,类似守护进程的逻辑......)而且我更多地询问有关这种情况的最佳实践.

我们以此代码为例:

module Blah
  extend self

  def run
     some_initializer_method
     loop do
        some_other_method
        yet_another_method
     end
  end
end
Run Code Online (Sandbox Code Playgroud)

我想Blah.run使用Rspec 测试方法(我也使用RR,但普通的rspec是一个可接受的答案).

我认为最好的方法是分解更多,比如将循环分成另一种方法或其他方法:

module Blah
  extend self

  def run
     some_initializer_method
     do_some_looping
  end

 def do_some_looping
   loop do
     some_other_method
     yet_another_method
   end
 end
end
Run Code Online (Sandbox Code Playgroud)

...这允许我们测试run和模拟循环...但是在某些时候需要测试循环内的代码.

那么在这种情况下你会怎么做?

根本就没有测试这个逻辑,这意味着测试some_other_method&yet_another_method但不do_some_looping

通过模拟在某个时刻让循环中断?

......别的什么?

tad*_*man 15

更实际的是在单独的线程中执行循环,声明一切正常,然后在不再需要时终止线程.

thread = Thread.new do
  Blah.run
end

assert_equal 0, Blah.foo

thread.kill
Run Code Online (Sandbox Code Playgroud)


zou*_*oul 10

如何在一个单独的方法中使用循环体,比如calculateOneWorldIteration?这样你就可以根据需要在测试中旋转循环.并且它不会损害API,它在公共界面中具有相当自然的方法.


小智 9

在rspec 3.3中,添加此行

allow(subject).to receive(:loop).and_yield
Run Code Online (Sandbox Code Playgroud)

你之前的钩子将简单地屈服于块而没有任何循环