Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rspec Mocking: ActiveRecord::AssociationTypeMismatch

I'm new to Rspec and trying to set up a test for a User Profile. Profile belongs_to User.

Now, I have an API integration with a third party site that works through the User Model, but some of the information for that API link is contained in Profile, so I have an "after_update" filter on Profile that tells the parent user to save, which triggers an update of the API.

I'm trying to write a test for this, and I'm getting an ActiveRecord::AssociationTypeMismatch. The reason is I'm using a mock user, but I'm trying to test that when Profile is updated it sends :save to User. Plus, the User model has an email confirmation process and the afformentioned API calls in it's create process, so it really isn't ideal to actually create a user just to test this out.

Here's my test:

it "should save the parent user object after it is saved" do
    user = double('user', :save => true )
    profile = Profile.create( :first_name => 'John', :last_name => 'Doe' )
    profile.user = user

    user.should_receive(:save)
end

So, clearly the ActiveRecord error is being caused by trying to associate a mock user with a profile that expects a real user to be associated.

My question is, how do you avoid this kind of problem in writing rails tests? All I want this test to do is make sure Profile calls :save on it's parent User. Is there a smarter way to do this, or a workaround for the ActiveRecord error?

Thanks!

like image 982
Andrew Avatar asked Feb 03 '11 05:02

Andrew


2 Answers

You should be able to use a mock_model for this:

it "should save the parent user object after it is saved" do
  user = mock_model(User)
  user.should_receive(:save).and_return(true)
  profile = Profile.create( :first_name => 'John', :last_name => 'Doe' )
  profile.user = user
end
like image 101
zetetic Avatar answered Oct 18 '22 12:10

zetetic


I found the only way I was able to get around this problem was to use a Factory user instead of a mock. That's frustrating, but when testing the callbacks between two ActiveRecord models you have to use the real models or else save calls will fail, the lifecycle won't happen, and the callbacks can't be tested.

like image 24
Andrew Avatar answered Oct 18 '22 14:10

Andrew