2009-07-22 2 views
32

C'è un modo per arrestare Kernel.sleep in uno scenario rspec?RSpec: Kernel stub :: sleep?

+0

Siete alla ricerca di qualcosa al di là Kernel :: stubs (: sleep) –

+0

Immagino che vorrebbe che funzioni e non dorme, forse rallentando il suo test ... – Rich

risposta

43

Se si chiama all'interno del contesto di un oggetto, si dovrebbe stub sul oggetto, in questo modo:

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 

la chiave è, a dormire su stub qualunque "io" è nel contesto in cui viene chiamato il sonno.

+1

Ha funzionato benissimo per me, evviva! – opsb

+0

Lo stub dell'oggetto non è una buona idea. Per esempi, vedi: http://robots.thoughtbot.com/don-t-stub-the-system-under-test – georgebrock

+1

@georgebrock per motivo non rilevante, non è vero? Credo che [questo] (http://stackoverflow.com/a/27749263/52499) sia il modo in cui si esprime meglio l'intenzione. E deve usare la sintassi più recente. 'allow_any_instance_of (Object) .per ricevere (: sleep)' –

2

Se stai usando Mocha, quindi qualcosa di simile a questo lavoro:

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 

Oppure, se si sta utilizzando 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 

È probabilmente non dovrebbe essere prova più problemi complessi di threading con test unitari. Nei test di integrazione, tuttavia, utilizzare il numero reale Kernel.sleep, che consente di risolvere problemi complessi di threading.

4

In puro 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 
+8

Per chiarire, perché questo non ha funzionato immediatamente, devi chiamare Kernel .sleep, per deriderlo in questo modo. Basta chiamare il sonno direttamente fallisce –

+0

Sì, il metodo che chiami ti farà dormire. – nitecoder

0

avevo bisogno di stub richiedere e dopo lunghe ricerche ho scoperto che l'unico modo che ha funzionato per me è questo sonno

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 
0

Non sono riuscito a far funzionare le altre soluzioni. Forse qualcosa è cambiato nel modo in cui il sonno viene gestito nelle versioni più recenti di Ruby o qualcos'altro.

Quello che ho finito è stato quello di eseguire il patch delle scimmie nella classe Oggetto in quanto sembra che questo sia ciò che riceve le chiamate a riposo. Così ho semplicemente aggiunto questo:

class Object 
    def sleep(*args) 
    end 
end 

Quindi il metodo del sonno ora non fa nulla al posto di qualcosa. Potrebbe esserci un modo per deriderlo meglio, ma non sono riuscito a trovare una buona soluzione senza prendere in giro lo sleep metohd di ogni singolo oggetto che potenzialmente lo utilizzava.

+0

Si prega di vedere la mia soluzione qui sotto. rspec-mock è qui, quindi non devi patch per scimmia – Benj

11

Quando la chiamata a sleep non è all'interno di un oggetto (durante la prova di un compito rastrello per esempio), è possibile aggiungere quanto segue in una prima del blocco (RSpec 3 sintassi)

allow_any_instance_of(Object).to receive(:sleep)