2012-12-20 14 views
11

Powiel możliwe:
Is it possible for RSpec to expect change in two tables?RSpec, spodziewać się zmienić z wielu wartości

it "should create a new Recipe" do 
    expect { click_button submit }.to change(Recipe, :count).by(1) 
end 

To pozwala mi sprawdzić, że model 'Receptura' ma jeszcze jedną pozycję, ale Chciałbym również sprawdzić, czy model "Składnik" ma jeszcze jeden wpis. Blok oczekiwania może zostać wykonany tylko raz, ponieważ formularz jest już przesłany.

Wiem, że mógłbym zrobić kolejny blok "to", ale uważam, że musi istnieć sposób SUSZENIA.

+0

To pytanie jest granicą dla codereview.stackexchange –

Odpowiedz

48

chciałbym zaproponować wyschnięciu przez przedefiniowanie przedmiotem badań (i przy użyciu stabby lambdas dla zabawy):

describe "recipe creation" do 
    subject { -> { click_button submit } } 
    it { should change(Recipe, :count).by(1) } 
    it { should change(Ingredient, :count).by(1) } 
end 

Aktualizacja: Chociaż może to wyglądać mniej DRY, te dni prawdopodobnie nadal będę nadal używać składni expect, ponieważ jest to recommended i generalnie odchodzę od should, ale być może wprowadzę pewne drobne zmiany dla specyfikacji readabi lity:

describe "recipe creation" do 
    let(:creating_a_recipe) { -> { click_button submit } } 

    it "changes the Recipe count" do 
    expect(creating_a_recipe).to change(Recipe, :count).by(1) 
    end 

    it "changes the Ingredient count" do 
    expect(creating_a_recipe).to change(Ingredient, :count).by(1) 
    end 
end 

Uwaga: można zobaczyć w RSpec documentation for the change matcher że expect używa klamrowych. Jest to oczywiście poprawne, ale powód, dla którego standardowy nawias działa w tym przykładzie, jest taki, że kod zmieniający stan zmienny (zawarty w creating_a_recipe) jest w lambda, który jest wywoływany, gdy jest przekazywany jako expect jako parametr.

Bez względu na to, w tym przypadku można z powodzeniem używać expect(creating_a_recipe) lub expect { creating_a_recipe }, a dowolne z nich jest dostosowane do osobistych preferencji.

+3

Pytanie jest teraz zamknięte, ale ze względu na to, '...} .to change {[val1, val2]} .from ([old_val1, old_val2])" działałoby dobrze. – zakelfassi

+0

Należy zauważyć, że konieczne jest wywołanie lambda, aby cokolwiek się wydarzyło. Używam nawiasów kwadratowych, aby to zrobić, tj. 'Creation_a_recipe []'. –

+1

'spodziewać się' zadzwoni do lamba jeśli zostanie przekazany. –

0

mogli Państwo streszczenie wszystkich, że do metody pomocnika

def test_creation_of(model) 
    it "should create a new #{model}" do 
    expect { click_button submit }.to change(model.constantize, :count).by(1) 
    end 
end 

Ale ja polecam tylko jeśli zrobisz to dla wielu modeli. W przeciwnym razie kod będzie trudniejszy do odczytania. Jeśli tak, najlepiej umieścić go w spec pomocnika.

Ponadto, w oparciu o inne precedensy w Twoich testach, możesz przekazać obiekt Const zamiast napisu (jak użyłem w powyższym przykładzie).

następnie

it "should create a new Recipe" do 
    test_creation_of('Recipe') 
    test_creation_of('Ingredient') 
end 
+0

dla przyszłości: ten kod działa. Downvotes jest generalnie niewłaściwe w tej sytuacji - powinieneś skomentować za pomocą nieporozumień (lub pokazać, dlaczego ten kod nie może rozwiązać problemu). –

+0

To jest miła abstrakcja do testowania tworzenia modelu, ale OP pytał o to, jak przetestować tworzenie dwóch modeli jednym kliknięciem. Masz jednak rację, to sprzyja lepszej społeczności do pisania komentarzy, a nie po prostu w dół. Mój błąd. –

+0

Co ciekawe, ponieważ minęły 2 dni, SO nie pozwala mi odebrać mojej wersji, dopóki nie zaktualizujesz odpowiedzi. –

Powiązane problemy