Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the right parameters for a rspec put request on my stub

I have a controller spec and I get following failed expectation:

 Failure/Error: put :update, :id => login_user.id, :user => valid_attributes
   #<User:0xbd030bc> received :update_attributes with unexpected arguments
     expected: ({:name=>"changed name", :email=>"[email protected]", :password=>"secret", :password_confirmation=>"secret"})
          got: ({"name"=>"Test user", "email"=>"[email protected]", "password"=>"secret", "password_confirmation"=>"secret"})

And for me it looks like I am passing in "name" => "Test User" and I am expecting :name => "test user"

my spec looks like this:

    describe 'with valid parameters' do
      it 'updates the user' do
       login_user = User.create!(valid_attributes)
       controller.stub(:current_user).and_return(login_user)
       User.any_instance.
          should_receive(:update_attributes).
          with(valid_attributes.merge(:email => "[email protected]",:name=>"changed name"))
       put :update, :id => login_user.id, :user => valid_attributes
      end 
end

and I have something like this for my valid attributes:

    def valid_attributes
  {
    :name => "Test user",
    :email=> "[email protected]",
    :password => "secret",
    :password_confirmation => "secret"

  }
end

so what is wrong with my parameters any suggestions?

I am using Rails 3.0.5 with rspec 2.6.0...

like image 218
server info Avatar asked Feb 25 '23 01:02

server info


1 Answers

The failure message is telling you exactly what's going on: any instance of User is expecting update_attributes with a hash including :email => "[email protected]", but it's getting :email => "[email protected]" because that's what's in valid_attributes. Similarly, it's expecting :name => "changed_name", but gets :name => "Test user" because that's what's in valid_attributes.

You can simplify this example and avoid this confusion. There is no need to use valid_attributes here because should_receive intercepts the update_attributes call anyhow. I usually do this like so:

controller.stub(:current_user).and_return(mock_model(User)) # no need for a real user here
User.any_instance.
  should_receive(:update_attributes).
  with({"these" => "params"})
put :update, :id => login_user.id, :user => {"these" => "params"}

This way the expected and actual values are right in the example and it makes clear that it doesn't really matter what they are: whatever hash is passed in as :user is passed directly to update_attributes.

Make sense?

like image 76
David Chelimsky Avatar answered Feb 26 '23 16:02

David Chelimsky