2011-05-04 23 views
12

Benim ApplicationController'da bir check_user_access_control before_filter var, bu da giriş yapmadan önce kullanıcının girişlerini ve izinlerini kontrol ediyor. Üzerinde bazı testler yazmaya çalışıyorum ve bunu yapmanın iyi bir yolunu bulamıyorum.Rails'de RSpec ile bir before_filter'in nasıl düzgün çalıştığını test etme

Basit indeks işlemleri için şunu yaparım:

it "allows access to mod" do 
    login_as(Factory(:mod)) # this is a spec helper 
    get :index 
    response.code.should == "200" 
end 

ve gayet iyi çalışıyor. Düzenleme/gösterme/oluşturma ve bazı paramıklara ihtiyaç duyan diğer eylemler, veritabanına olan etkileşimler ve çalıştırıldıktan sonra olası yeniden yönlendirme için, çok fazla başka malzemeye ihtiyaç vardır.

Belirli bir eylemin before_filters sonra adlandırılmış olup olmadığını test etmek için bir yolu var mı?response.code.should == "200" satırı ile değiştirmek için controller.should_receive(:action_name) (çalışmıyor) gibi bir şey arıyorum.

sürümleri: rails 3.0.4 ve rspec 2.5

Başka bir yaklaşım denedim. Xzx29 olarak adlandırdığım Applicationz Controller'da controller.should_receive(:redirect_to_login) ile çalıştığım ve çalıştığımız bir metodumuz var.

Kullanıcıya izin verilip verilmediğini doğru bir şekilde algılarken, yönteme dayandırılır; bu, denetleyicinin eyleminin kullanıcıya izin verilip verilmeyeceğini çalıştırması anlamına gelir. Ayrıca eylem, param ve veri tabanına da bağlıdır ve biz bunu istemiyoruz.

Şimdi controller.stub!(:action_name) ile eylem yöntemini koyarsam, eylem çalışmaz, ancak RSpec hala şablonu arıyordur. Eh, bazı eylemlerin şablonları yoktur, sadece umurumda değiliz redirect_to :action => :somewhere_else veya render :text => "foobar" ile bitiyorlar.

Sıralı olarak, şimdi ihtiyacım olan şey, RSpec NOT'in şablonun varlığı hakkında endişe etmenin bir yolunu bulmak.

cevap

7

, yine bir kukla uygulanmasını verebilir. Bu uygulamanın içinde, tüm yürütmenin durdurulduğundan emin olmak için bir hata oluşturabilir veya bir yönlendirmeyi zaten yapabilirsiniz.

E.g.

controller.should_receive(:redirect_to_log) { redirect_to login_url } 

veya

controller.should_receive(:redirect_to_log) { raise StandardError.new('login error') } 
expect { get :index }.to raise_error 

fazla bilgi için müthiş rspec documentation göz atın.

Yardım edin.

+0

yayınlanan ilk blok görünmüyordu çalışmak ama ikincisi (bir hata tutarsa ​​bir) bir cazibe gibi çalıştı! Şimdi, tam tersini yapmanın bir yolunu bulmak için: örnekte 'control.should_not_receive (: redirect_to_log)' bulunduğumuzda eylem yönteminin çalışmasını engelle. – Kostas

+0

Normalde, 'before_filter' olarak kullandığınız yöntemi kesinlikle bağımsız olarak test ederim: bir kullanıcı verildiğinde, erişime izin verilip verilmeyeceğine karar verir. Kontrol cihazınızda sadece test edebilirsiniz: eğer bir kullanıcıya erişime izin verilmemesi gerekiyorsa, o zaman “redirect_to_log” çağrılmalıdır (yukarıda gösterdiğim). Bir kullanıcının erişimi varsa, 'redirect_to_log' çağrılmamalı ve' response.status.should == 200' (bu durumda, görünümleri bulmakta zorluk çekmeyeceğinizi düşünüyorum). SO sadece başarılı bir şekilde çalıştığını test edin. – nathanvda

+0

Bu yaklaşımı denedim, ancak sorun, bazı eylemlerin (oluşturma gibi) bir 200 ile değil, 302 ile (gösterilecek yönlendirmeler) bitmesidir. Ayrıca, bazılarının by-pass yapmak istediğim bir dizi param ve fonksiyona DB erişimi (hatta bazıları için dosya sistemi erişimi bile) gerekiyor, çünkü sadece bu kadar çok saplayabiliyorsunuz. ** Aksiyon yöntemini kullanmak beni öldürüyor, çünkü bu izin testlerinin amacı değil zaten. ** – Kostas

0

@nathanvda's answer uzatmak için:

stubbing, yine bir kukla uygulanmasını verebilir. Bu uygulamanın içinde [...] yine de bir yönlendirme yapın.

Sen blokta controller belirtmek gerekir:

expect(controller).to receive(:redirect_to_log) { controller.redirect_to login_url } 

RSpec da yöntemini ararken önceliklidir redirect_to çağrılan bir eşleyici vardır.Doğrudan denetleyicide arama bunun etrafında çalışır. nathanvda sayesinde ile

0

Nihai çözüm,:

it "allows access to moderator" do 
    login_as(Factory(:mod)) 
    controller.stub!(action) { raise "HELL" } 

    controller.should_not_receive(:redirect_to_login) 
    expect { get action }.to raise_error(/HELL/) 
end 

it "denies access to user" do 
    login_as(Factory(:user)) 

    controller.should_receive(:redirect_to_login) { raise "HELL" } 
    expect { get :index }.to raise_error(/HELL/) 
end 

https://gist.github.com/957565