'Rspec 3 how to test flash messages
I want to test controller's action and flash messages presence with rspec.
action:
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
spec:
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
...
But I've got an error:
Failure/Error: expect(flash[:success]).to be_present
expected `nil.present?` to return true, got false
Solution 1:[1]
You are testing for the presence of flash[:success]
, but in your controller you are using flash[:notice]
Solution 2:[2]
The best way to test flash messages is provided by the shoulda gem.
Here are three examples:
expect(controller).to set_flash
expect(controller).to set_flash[:success]
expect(controller).to set_flash.now[:alert].to(/are not valid/)
Solution 3:[3]
If you are more interested in the content of the flash messages you can use this:
expect(flash[:success]).to match(/Reset password instructions have been sent to .*/)
or
expect(flash[:alert]).to match(/Can't find user with this email: .*/)
I would advise against checking for a specific message unless that message is critical and/or it does not change often.
Solution 4:[4]
With: gem 'shoulda-matchers', '~> 3.1'
The .now
should be called directly on the set_flash
.
Using set_flash
with the now
qualifier and specifying now
after other qualifiers is no longer allowed.
You'll want to use now
immediately after set_flash
. For instance:
# 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
Solution 5:[5]
The another approach is to leave out the fact that a controller has flash messages and write integration test instead. This way you increase the chances that you will not need to alter the test once you decide to show that message using JavaScript or by some another way.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | rabusmar |
Solution 2 | Meg Gutshall |
Solution 3 | |
Solution 4 | killerkiara |
Solution 5 |