简体   繁体   English

RSpec:存根内核::睡眠?

[英]RSpec: stubbing Kernel::sleep?

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

If you are calling sleep within the context of an object, you should stub it on the object, like so:如果你在一个对象的上下文中调用 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

The key is, to stub sleep on whatever "self" is in the context where sleep is called.关键是,在调用 sleep 的上下文中对任何“自我”进行存根。

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

allow_any_instance_of(Object).to receive(:sleep)

If you're using Mocha , then something like this will work:如果您使用的是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

Or if you're using rr :或者,如果您正在使用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

You probably shouldn't be testing more complex threading issues with unit tests.可能不应该使用单元测试来测试更复杂的线程问题。 On integration tests, however, use the real Kernel.sleep , which will help you ferret out complex threading issues.但是,在集成测试中,请使用真正的Kernel.sleep ,这将帮助您找出复杂的线程问题。

In pure rspec:在纯 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

Here's the newer way of stubbing Rspec with Kernal::Sleep .这是使用Kernal::Sleep存根 Rspec 的新方法。

This is basically an update to the following answer: Tony Pitluga's answer to the same question这基本上是对以下答案的更新: Tony Pitluga 对同一问题的回答

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

For rspec version 1, the stubbing syntax has changed.对于 rspec 版本 1,存根语法已更改。 This works:这有效:

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

When I use it.当我使用它时。

I needed to stub require and after long searching I found that the only way that worked for me is this我需要存根 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

I was not able to get the other solutions here to work.我无法在这里使用其他解决方案。 Maybe something have changed in the way sleep is handled in newer versions of Ruby, or something else.也许在较新版本的 Ruby 中处理 sleep 的方式发生了一些变化,或者其他什么。

What I ended up doing was to monkey-patch the Object class as it appears that this is what receives the sleep calls.我最终做的是对Object类进行猴子修补,因为这似乎是接收睡眠调用的内容。 So I simply added this:所以我简单地添加了这个:

class Object
    def sleep(*args)
    end
end

So the sleep method now does nothing in stead of something.所以 sleep 方法现在什么也不做,而是什么。 There might be some way of mocking this better, but I was not able to find a good solution without mocking the sleep metohd of every single object that potentially used it.可能有一些方法可以更好地模拟它,但是如果不sleep metohd可能使用它的每个对象的sleep metohd ,我就无法找到一个好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM