2014-07-23 72 views
52

我想用rspec測試控制器的動作和flash消息存在。Rspec 3如何測試Flash消息

行動

def create 
    user = Users::User.find_by_email(params[:email]) 
    if user 
    user.send_reset_password_instructions 
    flash[:success] = "Reset password instructions have been sent to #{user.email}." 
    else 
    flash[:alert] = "Can't find user with this email: #{params[:email]}" 
    end 

    redirect_to root_path 
end 

規格

describe "#create" do 
    it "sends reset password instructions if user exists" do 
    post :create, email: "[email protected]"  
    expect(response).to redirect_to(root_path) 
    expect(flash[:success]).to be_present 
    end 
... 

但我得到了一個錯誤:

Failure/Error: expect(flash[:success]).to be_present 
    expected `nil.present?` to return true, got false 

回答

48

您正在測試的flash[:success]存在,但在你的c您正在使用的遙控器flash[:notice]

+0

哦,對不起,我只是在這裏滑了。 與閃存相同的錯誤[:notice] – MikeAndr

+2

在這種情況下,問題可能在於您的控制器代碼和/或測試數據。嘗試將'expect(flash [:notice])''更改爲'expect(flash [:alert])',如果測試通過,那麼可能只是測試郵件不存在。 – rabusmar

32

測試閃光消息的最佳方法是由shoulda寶石提供。

這裏有三個例子:

expect(controller).to set_flash 
expect(controller).to set_flash[:success] 
expect(controller).to set_flash[:alert].to(/are not valid/).now 
+0

真棒,不知道這個! :) – Loed

14

如果您更感興趣的是閃光燈消息的內容,你可以使用這個:

expect(flash[:success]).to match(/Reset password instructions have been sent to .*/) 

expect(flash[:alert]).to match(/Can't find user with this email: .*/) 

我會建議不要檢查特定的消息,除非該消息非常重要和/或不經常更改。

0

另一種方法是忽略控制器具有閃存消息並寫入集成測試的事實。通過這種方式,您可以增加一旦決定使用JavaScript或其他方式顯示該消息時,不需要更改測試的機會。

https://stackoverflow.com/a/13897912/2987689

0

看到:gem 'shoulda-matchers', '~> 3.1'

.now應直接在set_flash被調用。

使用set_flashnow限定符和其它限定詞之後指定now不再允許。

您需要在set_flash之後立即使用now。例如:

# Valid 
should set_flash.now[:foo] 
should set_flash.now[:foo].to('bar') 

# Invalid 
should set_flash[:foo].now 
should set_flash[:foo].to('bar').now