2011-07-15 12 views
7

Używam Rails 3 i RSpec 2.6.0.Jak napisać makro kontrolera RSpec, które może akceptować argumenty zdefiniowane przez let lub w bloku before?

Nie jestem pewien, czy to możliwe, ale tutaj jest to, co chciałbym zrobić:

describe UsersController do 
    let(:user) { Fabricate :user } 
    describe "GET /user/:id" do 
    should_return_401_code_if_user_is_not_confirmed :get, :show, :id => user.id 
    end 
    describe "PUT /user/:id" do 
    should_return_401_code_if_user_is_not_confirmed :put, :update, :id => user.id 
    end 
end 

starałem się wdrożyć makro takiego:

module ControllerMacros 
    def should_return_401_code_if_user_is_not_confirmed(verb, action, params = {}) 
    it "returns a 401 code if the user is not an admin" do 
     send verb, action, params 
     response.code.should == "401" 
    end 
    end 
end 

Ale gdy uruchomiony te specyfikacje dostaję błąd undefined local variable or method 'user'. Próbowałem przejść do zmiennej @user zdefiniowanej w bloku before, ale to też nie działa. Podejrzewam, że to dlatego, że nie jestem w przykładowym bloku.

Czy można przekazać do makra kontrolera zdefiniowanego przez let lub w bloku before?

Dzięki!

+0

Być może warto rozważyć refaktoryzację testu. W twoim teście nie warto mieć dwóch warunków - obecność "jeśli" jest zapachem testowym. Czy testujesz, czy użytkownik jest potwierdzony, czy też po prostu zwraca odpowiedni kod? Jeśli to drugie * ustaw * potwierdzenie zamiast go sprawdzić. –

Odpowiedz

6

Od czytania przez this thread na liście użytkowników rspec, wydaje się, że odpowiedź brzmi nie. Problem polega na tym, że twoje zmienne let/before nie są inicjowane aż do bloku it w ciele twojego makra, więc nie możesz odwoływać się do nich jako parametrów do wywołania makr.

Próbuję zrobić zasadniczo to samo na stronie, nad którą pracuję. Rozwiązaniem, do którego zmierzam, jest wywołanie metody makra z blokiem, który zwróci żądany skrót params, a następnie użyj instance_eval w treści makra, aby ocenić blok przy użyciu zasięgu makra.

#spec 
... 
describe "GET /user/:id" do 
    should_return_401_code_if_user_is_not_confirmed :get, :show { {:id => user.id} } 
end 

#macro 
... 
def should_return_401_code_if_user_is_not_confirmed(verb, action, &params_block) 
    it "returns a 401 code if the user is not an admin" do 
    params = instance_eval &params_block 
    send verb, action, params 
... 
Powiązane problemy