2012-07-03 2 views
8

Я тестирую кусок кода Rails, который гласит:Какой сон() используется Rails?

sleep(10.0) 

В моих тестах RSpec, называя:

Kernel.should_receive(:sleep).exactly(1).time 

не удалось, и тест спал в течение десяти секунд. Это привело меня к выводу, что sleep() в программе Rails не звонит Kernel.sleep(). Я проверил это, изменив мой Rails код:

Kernel.sleep(10.0) 

... после чего мои тесты RSpec прошли (и тест не спал).

Это приводит к специфическому и общий вопрос:

  • Что реализация сна() не использовать Rails (я бегу Руби 1.9.3/Rails 3.2.1)?
  • От интерпретатора, какой самый простой способ найти исходный код для любой функции?
+0

Единственный метод 'sleep', который я могу найти в ruby ​​api, это' Mutex # sleep', так что может быть он: http://apidock.com/ruby/Mutex/sleep – Frost

+1

Если вы хотите спросить два вопроса, вы должны задать два вопроса. Я решил игнорировать второй вопрос в своем ответе, поскольку он уже задан и несколько раз ответил на StackOverflow. –

+0

Jorg: Я знал об опасности сразу задавать два вопроса! Спасибо ... –

ответ

8

Неявный приемник, если вы не указали явный, составляет self, а не Kernel. (Почему вы думаете, что?)

Так,

sleep(10.0) 

примерно такой же, как

self.sleep(10.0) 

и не совсем такой же, как

Kernel.sleep(10.0) 

Так , он звонит Kernel#sleep по номеру self, а не по номеру Kernel. Это означает, что вам нужно установить ожидаемое значение для любого объекта self в этом конкретном методе.

+0

Doh. Конечно. Это делает тестирование сложнее, так как sleep() может быть несколько слоев вниз, а 'self', о котором идет речь, не доступно. Мое решение - не оптимальное - заключалось в том, чтобы изменить исходный код, чтобы явно вызвать Kernel.sleep(). –

+0

Вы можете обезглавить патч 'Kernel # sleep', чтобы вызвать исключение, если оно вызывается более одного раза или с аргументом, отличным от 10.0, и затем утверждать, что исключение не создано. Или, вместо того, чтобы обезвреживать «Ядро», вы можете обезьянку патчить класс любого «самого себя». –

+0

Но на самом деле, похоже, вы тестируете неправильную вещь или на неправильном уровне. Почему вы не можете получить ссылку на объект, чтобы установить на него ожидание? Что такое * фактическое * поведение, которое вы хотите достичь, и действительно ли вы заботитесь о том, достигается ли это конкретное поведение одним вызовом 'sleep (10.0)' или двумя вызовами 'sleep (5.0)'? –

Смежные вопросы