45

有没有办法在 rspec 场景中存根 Kernel.sleep ?

4

8 回答 8

52

如果你在一个对象的上下文中调用 sleep,你应该在对象上存根它,像这样:

class Foo
  def self.some_method
    sleep 5
  end
end

it "should call sleep" do
  Foo.stub!(:sleep)
  Foo.should_receive(:sleep).with(5)
  Foo.some_method
end

关键是,在调用 sleep 的上下文中对任何“self”进行存根。

于 2009-08-20T03:44:20.777 回答
24

当调用sleep不在对象内时(例如在测试 rake 任务时),您可以在 before 块中添加以下内容(rspec 3 语法)

allow_any_instance_of(Object).to receive(:sleep)
于 2015-01-02T22:16:28.727 回答
4

如果您使用的是Mocha,那么这样的事情会起作用:

def setup
  Kernel.stubs(:sleep)
end

def test_my_sleepy_method
  my_object.take_cat_nap!
  Kernel.assert_received(:sleep).with(1800) #should take a half-hour paower-nap
end

或者,如果您使用的是rr

def setup
  stub(Kernel).sleep
end

def test_my_sleepy_method
  my_object.take_cat_nap!
  assert_received(Kernel) { |k| k.sleep(1800) }
end

可能不应该使用单元测试来测试更复杂的线程问题。但是,在集成测试中,请使用 real Kernel.sleep,这将帮助您找出复杂的线程问题。

于 2009-07-23T12:12:40.110 回答
4

在纯 rspec 中:

before do
  Kernel.stub!(:sleep)
end

it "should sleep" do
  Kernel.should_receive(:sleep).with(100)
  Object.method_to_test #We need to call our method to see that it is called
end
于 2009-07-30T11:22:16.913 回答
3

这是将 Rspec 与Kernal::Sleep.

这基本上是对以下答案的更新:Tony Pitluga's answer to the same question

class Foo
  def self.some_method
    sleep 5
  end
end

it "should call sleep" do
  allow_any_instance_of(Foo).to receive(:sleep)
  expect(Foo).to receive(:sleep).with(5)
  Foo.some_method
end
于 2019-11-30T05:48:55.133 回答
2

对于 rspec 版本 1,存根语法已更改。这有效:

allow_any_instance_of(Kernel).to receive(:sleep).and_return("")

当我使用它时。

于 2020-10-25T11:45:02.440 回答
0

我需要存根 require,经过长时间的搜索,我发现唯一对我有用的方法是

def method_using_sleep
  sleep
  sleep 0.01
end

it "should use sleep" do
  @expectations = mock('expectations')
  @expectations.should_receive(:sleep).ordered.with()
  @expectations.should_receive(:sleep).ordered.with(0.01)

  def sleep(*args)
    @expectations.sleep(*args)
  end

  method_using_sleep
end
于 2009-08-17T01:03:43.350 回答
0

我无法在这里使用其他解决方案。也许在较新版本的 Ruby 或其他东西中处理睡眠的方式发生了一些变化。

我最终做的是对Object类进行猴子补丁,因为它似乎是接收睡眠调用的内容。所以我简单地添加了这个:

class Object
    def sleep(*args)
    end
end

所以 sleep 方法现在什么也不做。sleep metohd可能有一些方法可以更好地模拟这个,但如果不模拟可能使用它的每个对象,我就无法找到一个好的解决方案。

于 2014-10-22T11:34:08.753 回答