Sono un neofita degli oggetti di simulazione e sto cercando di imparare come usarli in RSpec. Qualcuno può per piacere postare un esempio (un esempio di tipo di mondo di oggetto RSpec Mock ciao), o un link (o qualsiasi altro riferimento) su come usare l'API dell'oggetto mock RSpec?Esempio di oggetto simulato RSpec
risposta
Ecco un esempio di una semplice finta che ho fatto per un test di controllo in un'applicazione rotaie:
before(:each) do
@page = mock_model(Page)
@page.stub!(:path)
@page.stub!(:find_by_id)
@page_type = mock_model(PageType)
@page_type.stub!(:name)
@page.stub!(:page_type).and_return(@page_type)
end
In questo caso, sto beffardo i modelli pagetype Pagina & (oggetti) e spegnendo alcuni dei metodi che chiamo.
Questo mi dà la possibilità di eseguire un test come questo:
it "should be successful" do
Page.should_receive(:find_by_id).and_return(@page)
get 'show', :id => 1
response.should be_success
end
So che questa risposta è più rotaie specifica, ma spero che ti aiuta un po '.
Modifica
Ok, ecco un esempio del mondo ciao ...
Dato il seguente script (hello.rb):
class Hello
def say
"hello world"
end
end
Possiamo creare la seguente specifica (hello_spec.rb):
require 'rubygems'
require 'spec'
require File.dirname(__FILE__) + '/hello.rb'
describe Hello do
context "saying hello" do
before(:each) do
@hello = mock(Hello)
@hello.stub!(:say).and_return("hello world")
end
it "#say should return hello world" do
@hello.should_receive(:say).and_return("hello world")
answer = @hello.say
answer.should match("hello world")
end
end
end
Non ho abbastanza punti per inviare un commento ad una risposta, ma volevo dire che la risposta accettata mi ha aiutato anche a cercare di capire come stub in un valore casuale.
avevo bisogno di essere in grado di stub valore di istanza di un oggetto che viene assegnato in modo casuale ad esempio:
class ClumsyPlayer < Player do
def initialize(name, health = 100)
super(name, health)
@health_boost = rand(1..10)
end
end
Poi nella mia spec Ho avuto un problema sul capire come stub la salute casuale del giocatore maldestro di testare che quando ottengono una guarigione, ottengono la spinta giusta per la loro salute.
Il trucco era:
@player.stub!(health_boost: 5)
Quindi stub!
è stata la chiave, mi era stato appena usando stub
ed ero ancora ricevendo passaggi RSpec casuali e fallimenti.
Quindi grazie Brian
corrente (3.x) RSpec fornisce entrambi gli oggetti puri finte (come in tokhi's answer) e beffardo parziale (beffardo chiamate a un oggetto esistente). Ecco un esempio di derisione parziale. Utilizza expect
e receive
per simulare una chiamata di Order
a CreditCardService
, in modo che il test passi solo se la chiamata viene effettuata senza doverla effettivamente eseguire.
class Order
def cancel
CreditCardService.instance.refund transaction_id
end
end
describe Order do
describe '#cancel' do
it "refunds the money" do
order = Order.new
order.transaction_id = "transaction_id"
expect(CreditCardService.instance).to receive(:refund).with("transaction_id")
order.cancel
end
end
end
In questo esempio il mock è il valore restituito CreditCardService.instance
, che è presumibilmente un singoletto.
with
è facoltativo; senza di essa, qualsiasi chiamata a refund
soddisferebbe le aspettative. Un valore di ritorno può essere dato con and_return
; in questo esempio non viene utilizzato, quindi la chiamata restituisce nil
.
Questo esempio utilizza corrente (expect .to receive
) sintassi beffardo di RSpec, che funziona con qualsiasi oggetto. La risposta accettata utilizza il vecchio metodo rspec-rails mock_model
, che era specifico per i modelli ActiveModel ed è stato spostato da rspec-rails in un'altra gemma.
grazie per l'esempio, deff. aiutato – agentbanks217
Stai configurando un oggetto fittizio della classe che dovresti speculare/test, il che significa che non stai esercitando la classe in fase di sviluppo. Inutile. Mocking ha lo scopo di aiutarti a circondare la classe/il sistema in prova con oggetti che si fingono credibilmente come un ambiente reale, anche se più semplice/controllato/autonomo. È un anti-pattern per usare Mocking per controllare i meccanismi interni della classe che si sta sviluppando. –
Inoltre, questa risposta non è aggiornata. Vedi [tokhi's answer below] (https://stackoverflow.com/a/39573538/634576) su come scrivere un oggetto mock puro e [mio] (https://stackoverflow.com/a/39186152/634576) per come fare il mocking parziale in RSpec corrente. –