2011-05-10 11 views
50

Ho una famiglia modello con un metodo location che unisce le uscite location di altri oggetti, Membri. (I membri sono associati con le famiglie, ma questo non è importante qui.)Il metodo stoppato RSpec può restituire valori diversi in sequenza?

Ad esempio, dato

  • member_1 ha location == 'di San Diego (viaggio, restituisce 15 maggio)'
  • member_2 ha location == 'San Diego'

Family.location potrebbe restituire 'San Diego (membro_1 viaggiando, restituisce 15 maggio)' Le specifiche non sono importanti.

Per semplificare il test di Family.location, voglio stub Member.location. Tuttavia, ho bisogno di restituire due valori diversi (specificati) come nell'esempio sopra. Idealmente, questi sarebbero basati su un attributo di member, ma la semplice restituzione di valori diversi in una sequenza sarebbe OK. C'è un modo per farlo in RSpec?

È possibile sovrascrivere il metodo Member.location all'interno di ciascun esempio di test, come

it "when residence is the same" do 
    class Member 
    def location 
     return {:residence=>'Home', :work=>'his_work'} if self.male? 
     return {:residence=>'Home', :work=>'her_work'} 
    end 
    end 
    @family.location[:residence].should == 'Home' 
end 

ma dubito questo è buona pratica. In ogni caso, quando RSpec esegue una serie di esempi, non ripristina la classe originale, quindi questo tipo di override "avvelena" gli esempi successivi.

Quindi, c'è un modo per avere un metodo stub restituito valori diversi, specificati su ogni chiamata?

risposta

108

È possibile eseguire lo stub di un metodo per restituire valori diversi ogni volta che viene chiamato;

allow(@family).to receive(:location).and_return('first', 'second', 'other') 

Così la prima volta che si chiama @family.location tornerà 'prima', la seconda volta che tornerà 'secondo', e tutte le volte successive si chiamano, ritornerà 'altra'.

+0

Grazie per il tip – apneadiving

+0

Grazie, idlefingers! –

+0

Grazie a @idlefingers! Cosa succede se si desidera restituire un numero elevato di valori però? –

0

Ho provato la soluzione qui sopra ma non funziona per il mio. Ho risolto il problema con lo stubing con un'implementazione sostitutiva.

Qualcosa di simile:

@family.stub(:location) { rand.to_s } 
12

RSpec 3 sintassi:

allow(@family).to receive(:location).and_return("abcdefg", "bcdefgh") 
0

Se per qualche motivo si desidera utilizzare la vecchia sintassi, è ancora possibile:

@family.stub(:location).and_return('foo', 'bar') 
Problemi correlati