Подтвердить что ты не робот

RSpec: stubbing Kernel:: sleep?

Есть ли способ заглушить Kernel.sleep в сценарии rspec?

4b9b3361

Ответ 1

Если вы вызываете сон в контексте объекта, вы должны заглушить его на объекте, например:

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

Ключ состоит в том, чтобы заглушить сон на любом "я" в контексте вызова сна.

Ответ 2

Когда вызов sleep не входит в объект (например, при проверке задачи рейка), вы можете добавить следующее в перед блоке (синтаксис rspec 3)

allow_any_instance_of(Object).to receive(:sleep)

Ответ 3

В чистом 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

Ответ 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

Вероятно, вам не следует тестировать более сложные проблемы с потоками с помощью модульных тестов. Однако при тестировании интеграции используйте реальный Kernel.sleep, который поможет вам выявить сложные проблемы с потоками.

Ответ 5

Мне нужно было заглушить, и после долгих поисков я обнаружил, что единственный способ, который работал у меня, - это

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

Ответ 6

Мне не удалось заставить другие решения работать. Возможно, что-то изменилось в том, как сон обрабатывается в новых версиях Ruby или что-то еще.

То, что я закончил, - это обезвредить класс Object, поскольку, как представляется, это то, что получает вызовы сна. Поэтому я просто добавил это:

class Object
    def sleep(*args)
    end
end

Таким образом, метод сна теперь ничего не делает вместо чего-то. Возможно, какой-то способ издеваться над этим лучше, но я не смог найти хорошее решение, не издеваясь над sleep metohd каждого отдельного объекта, который его потенциально использовал.