2012-12-20 17 views
11
ile değiştirmesini bekliyoruz

Olası Çoğalt: Bu bana 'Reçete' modeli bir daha girişinin olmadığını kontrol etmenizi sağlar
Is it possible for RSpec to expect change in two tables?RSpec Birden çok değere

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

ama 'Hammadde' modelinin bir tane daha girişe sahip olduğunu da kontrol etmek isterim. Beklenen blok, form zaten gönderildiği için yalnızca bir kez gerçekleştirilebilir.

Başka bir 'it' bloğu yapabileceğimi biliyorum, fakat bir DRYer yolu olması gerektiğini hissediyorum.

+0

Bu soru, gelecek için codereview.stackexchange –

cevap

48

Ben madde üzerinde test yeniden tanımlanması (ve eğlence için stabby lambdas kullanarak) tarafından o kadar kurutma önereceğini:

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

Güncelleme: daha az KURU görünse, bu günüm hala recommended olduğu için expect sözdizimini kullanmaya devam edeceğim ve genellikle should'dan uzaklaşıyorum, ama belki de bazı özellikler değişebilir vasıflı:

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 

Not: Eğer expect küme parantezi kullanılır RSpec documentation for the change matcher içinde görebilirsiniz. Bu elbette doğrudur, ancak bu örnekte standart parantezin çalışmasının nedeni, değiştirilebilen durumu değiştiren kodun (creating_a_recipe'da yer alan) bir parametre olarak expect'a iletildiğinde çağrılan bir lambda olmasıdır.

Bu durumda, ya expect(creating_a_recipe) ya da expect { creating_a_recipe } ya da bunlardan hangisi olursa olsun, başarılı bir şekilde kullanılabilir ve hangisini kullanırsanız kullanın, kişisel tercihinize göre.

+3

Soru şu anda kapalı, ancak bunun uğruna, ... ...}. {[Val1, val2]} değerini değiştirmek için. [[Old_val1, old_val2]) 'sadece iyi çalışırdı. – zakelfassi

+0

Gerçekleşecek her şey için lambda'yı çağırmanın gerekli olduğunu unutmayın. Bunu yapmak için köşeli parantezler kullanıyorum, yani 'create_a_recipe [] '. –

+1

"bekliyor", biri içeri aktarılırsa bir lamba arayacaktır. –

0

Yapabilirsin bir yardımcı yöntemiyle

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 

Ama birçok model için bunu yapacak olursa sadece tavsiye ederim içine soyut bütün bunlar. Else sadece kodu okumayı zorlaştıracak. Eğer yaparsan, en iyisini bir yardımcıya koy.

Ayrıca, testlerinizdeki diğer örneklere dayanarak, bir String yerine bir Const nesnesini geçirebilirsiniz (yukarıdaki örnekte kullandığım gibi).

sonra

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

için sınırdır: bu kod çalışır. Bu durumda Downvotes genellikle uygunsuzdur - bunun yerine anlaşmazlık ile yorum yapmalısınız (veya bu kodun sorunu neden çözemediğini gösteriniz). –

+0

Bu, bir modelin oluşturulmasının test edilmesi için güzel bir soyutlamadır, ancak OP, tek bir tıklamayla iki modelin oluşturulmasının nasıl test edileceğini sormaktaydı. Yine de haklısınız, sadece küçültmekten ziyade yorum yazmak için daha iyi bir toplumu teşvik ediyor. Benim hatam. –

+0

İlginç bir şekilde, 2 gün olduğu için, SO yanıtı güncellemeden beni reddetmeme izin vermiyor. –