2013-05-22 4 views
7

Ho una suite di test strutturato in questo modo:Come posso "aspettare" prima del blocco per cambiare qualcosa in rspec?

let(:cat) { create :blue_russian_cat } 
subject { cat } 

context "empty bowl" do 
    let!(:bowl) { create(:big_bowl, amount: 0) } 
    before { meow } 

    # a ton of `its` or `it` which require `meow` to be executed before making assertion 
    its(:status) { should == :annoyed } 
    its(:tail) { should == :straight } 
    # ... 

    # here I want to expect that number of PetFishes is going down after `meow`, like that 
    it "will eat some pet fishes" do 
    expect {???}.to change(PetFish, :count).by(-1) 
    end 
end 

solito vorrei solo mettere questo blocco al di fuori del contesto è stata chiamata expect così:

it "will eat some pet fishes" do 
    expect { meow }.to change(PetFish, :count).by(-1) 
    end 

ma rende il codice un po 'più difficile da leggere, poiché il codice correlato è collocato al di fuori del suo contesto.

risposta

4

Vuoi pensare di cambiare entrambi i test per expect sintassi per farli sotto lo stesso context? Forse qualcosa di simile:

let(:cat) { create :blue_russian_cat } 

context "empty bowl" do 
    let!(:bowl) { create(:big_bowl, amount: 0) } 
    let(:meowing) { -> { meow } } # not sure what meow is, so may not need lambda 

    it "will annoy the cat" do 
    expect(meowing).to change(cat.status).from(:placid).to(:annoyed) 
    end 

    # here I want to expect that number of PetFishes is going down after `meow` 
    it "will eat some pet fishes" do 
    expect(meowing).to change(PetFish, :count).by(-1) 
    end 
end 
+0

Idea interessante, anche se la riscrittura di tutti i test in modalità 'expect' sembra essere scomoda. – Andrew

+1

@Andrew Mi ci vuole un po 'di tempo se si hanno molti test, ma penso che ne varrà la pena a lungo andare perché sembra che la sintassi 'expect' sarà [la sintassi predefinita per RSpec che si muove in avanti] (http: //myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax) ed è [consigliato per nuovi progetti] (http://branch.com/b/which-rspec-syntax-do -preferisci). Ma questa è principalmente una questione di gusti e preferenze sintattiche. –

+0

grazie, è stato inaspettatamente perspicace. – Andrew

3

Non si impostano le aspettative sul blocco before. Il suo scopo è quello di impostare l'ambiente (ed è anche eseguito prima delle specifiche, quindi è troppo tardi per aspettarsi qualcosa di esso). Vuoi regolare let.

context "empty bowl" do 
    let(:cat) { meow } 

    # here I want to expect that number of PetFishes is going down after `meow`, like that 
    it "will eat some pet fishes" do 
    expect {cat}.to change(PetFish, :count).by(-1) 
    end 
end 
+0

Quindi, non c'è modo di metterli entrambi nello stesso contesto? – Andrew

+0

Cosa intendi? –

+1

Ho un contesto in cui voglio eseguire il numero di specifiche, la maggior parte richiede "meow" per essere chiamato prima di fare l'asserzione, ma ce ne sono alcune che hanno "aspettarsi" in esse, quindi posso chiamare "before" prima } 'o metti l'invocazione' meow' dentro ogni caso, l'ultimo sembra una cattiva idea. – Andrew

0

mi rendo conto che l'utilizzo di variabili di istanza è proprio l'ideale, ma se la vostra sensibilità lo permettono, si potrebbe fare questo:

context "empty bowl" do 
    # ... 
    before { @pet_fish_change = change_to(PetFish, :count) {meow} } 

    it "will eat some pet fishes" do 
    expect(@pet_fish_change).to eq(-1) 
    end 

    # ... 

end 

che richiede che si definisce un metodo di change_to aiutante ma è molto semplice:

def change_to(obj, method, &block) 
    before = obj.send method 
    yield 
    (obj.send method) - before 
end 
Problemi correlati