C'è un modo per arrestare Kernel.sleep in uno scenario rspec?RSpec: Kernel stub :: sleep?
risposta
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.
Ha funzionato benissimo per me, evviva! – opsb
Lo stub dell'oggetto non è una buona idea. Per esempi, vedi: http://robots.thoughtbot.com/don-t-stub-the-system-under-test – georgebrock
@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)' –
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.
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
Per chiarire, perché questo non ha funzionato immediatamente, devi chiamare Kernel .sleep, per deriderlo in questo modo. Basta chiamare il sonno direttamente fallisce –
Sì, il metodo che chiami ti farà dormire. – nitecoder
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
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.
Si prega di vedere la mia soluzione qui sotto. rspec-mock è qui, quindi non devi patch per scimmia – Benj
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)
Siete alla ricerca di qualcosa al di là Kernel :: stubs (: sleep) –
Immagino che vorrebbe che funzioni e non dorme, forse rallentando il suo test ... – Rich