2012-07-03 10 views
8

Estoy probando una pieza de código que lee Rieles:¿qué sueño() usa Rails?

sleep(10.0) 

En mis pruebas RSpec, llamando al:

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

fallaron la prueba y durmió durante diez segundos. Esto me llevó a concluir que sleep() en un programa de Rails no está llamando al Kernel.sleep(). Verifiqué esto cambiando mi código rieles a:

Kernel.sleep(10.0) 

... después de lo cual pasaron mis pruebas RSpec (y la prueba de no dormir).

Esto conduce a una específica y una pregunta general:

  • Qué aplicación de sueño() Cómo utiliza rieles (estoy corriendo de Ruby 1.9.3/3.2.1 rieles)?
  • Según el intérprete, ¿cuál es la forma más fácil de encontrar el código fuente para cualquier función?
+0

El único otro método de "suspensión" que puedo encontrar en la aplicación de ruby ​​es el 'Mutex # sleep', por lo que podría ser: http://apidock.com/ruby/Mutex/sleep – Frost

+1

Si desea preguntar dos preguntas, debes hacer dos preguntas. Elegí ignorar la segunda pregunta en mi respuesta, ya que ya se ha preguntado y respondido varias veces en StackOverflow. –

+0

Jorg: ¡Yah, era consciente de los peligros de hacer dos preguntas a la vez! Gracias ... –

Respuesta

8

El receptor implícito, cuando no especifica uno explícito, es self, no Kernel. (¿Por qué piensa eso?)

Así,

sleep(10.0) 

es aproximadamente el mismo que

self.sleep(10.0) 

y no en absoluto lo mismo que

Kernel.sleep(10.0) 

Así , está llamando al Kernel#sleep en self y no en Kernel. Lo que significa que debe establecer una expectativa sobre cualquier objeto que self tenga en ese método en particular.

+0

Doh. Por supuesto. Eso hace que las pruebas sean más difíciles, ya que el sueño() puede estar varias capas abajo y el "yo" en cuestión no es fácilmente accesible. Mi solución, no óptima, fue cambiar el código fuente para llamar explícitamente a Kernel.sleep(). –

+0

Podría parchear el par 'Kernel # sleep' para levantar una excepción si se llama más de una vez o con un argumento diferente de 10.0 y luego afirmar que no se produce ninguna excepción. O, en lugar de parchear mono 'Kernel', podrías parchear mono la clase de lo que sea 'self'. –

+0

Pero en realidad, parece que estás probando lo incorrecto o en el nivel incorrecto. ¿Por qué no podría obtener una referencia al objeto para establecer una expectativa sobre él? ¿Cuál es el comportamiento * real * que desea lograr, y realmente se preocupa usted de si ese comportamiento en particular se logra mediante una sola llamada a 'sleep (10.0)' o dos llamadas a 'sleep (5.0)'? –