user3809888 February 2016

How do I unit test a Rails model that returns a different model object?

I have defined a User model and a Profile:

class User < ActiveRecord::Base
  has_one :profile

  def current_profile
    profile || create_profile
  end
end

So the current_profile method either returns the existing profile or creates a new one and returns it. How do I write a unit test for the User to check that this method works properly? Should I somehow check that the returned object is a Profile object? Or should I just check the profile's parameters? I am using RSpec not minitest.

Answers


Dharam February 2016

You should test for both cases:

either returns the existing profile OR creates a new one and returns it

using contexts:

describe 'User' do
  describe 'current_profile' do
    context 'when there is an existing profile' do
      it 'should return the existing profile' do
        # call and test expectations
      end
    end

    context 'when there is no existing profile' do
      it 'should create and return the profile' do
        # call and test expectations
      end
    end
  end
end

Also remember to cover the case when the Role itself is a new_record. In which case create_profile may fail as it would expect a role id which doesn't exist yet.


jvillian February 2016

Perhaps something like:

describe User do
  describe 'current_profile' do
    context 'when there is an existing profile' do
      before(:each) do
        @profile = User.current_profile # creates a profile
      end
      it 'should return the existing profile' do
        expect(User.current_profile).to eq(@profile)
      end
      it 'should not change Profile.count' do # assuming you have a Profile Class
        expect{User.current_profile}.not_to change{Profile.count}
      end
      it 'should return a Profile object' do
        expect(@profile).to be_a(Profile)
      end
    end
    context 'when there is no existing profile' do
      it 'should change Profile.count by 1' do
        expect{User.current_profile}.to change{Profile.count}.by(1)
      end
      it 'should return a Profile object' do
        @profile = User.current_profile
        expect(@profile).to be_a(Profile)
      end
    end
  end
end

Post Status

Asked in February 2016
Viewed 3,557 times
Voted 8
Answered 2 times

Search




Leave an answer