Rspec 3如何testingFlash消息

我想用rspec来testing控制器的动作和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@example.com" 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 

您正在testingflash[:success]的存在,但在您的控制器中使用flash[:notice]

testingFlash消息的最好方法是由shoulda gem提供。

这里有三个例子:

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

如果你对Flash消息的内容更感兴趣,你可以使用这个:

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

要么

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

我build议不要检查一个特定的消息,除非这个消息是关键的和/或不经常改变。

另一种方法是忽略控制器具有闪存消息并写入集成testing的事实。 这样,当您决定使用JavaScript或其他方式显示该消息时,可以增加您不需要更改testing的机会。

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

用: gem 'shoulda-matchers', '~> 3.1'

应该直接在set_flash上调用set_flash

使用带有now限定符的set_flash ,并且不再允许在其他限定符之后指定。

您将立即在set_flash之后立即使用。 例如:

 # 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