user468311
user468311

Reputation:

How do I test associated models with Rspec

In my app I have following models:

class UserApplication < ActiveRecord::Base
  has_many :builds, dependent: :destroy
  belongs_to :user
end


class Build < ActiveRecord::Base
  belongs_to :user_application
end

And User model is generated by Devise.

My question is: is I want to test, say, model validations, should I do it like this:

require 'spec_helper'

describe UserApplication do

  it "is invalid without name" do
    user_application = UserApplication.new(name: nil)
    expect(user_application).to have(1).errors_on(:name)
  end
end

Or should I create UserApplication through User? In general, should I bear in mind associations when testing my models, if test example is not connected to relationships?

Upvotes: 0

Views: 2105

Answers (2)

Nikita Avvakoumov
Nikita Avvakoumov

Reputation: 262

It seems prudent to have test code parallel app code as closely as possible. That is, if UserApplication will be created via User in the controller, it ought to be done the same way in the test. Furthermore, your UserApplication validations will probably test the association sooner or later anyway, so the test subject should be created in such a way as to be valid. With that in mind, you can set up your tests as follows:

require 'spec_helper'

describe UserApplication do
  let(:user) { User.create(user_params) }
  before { @user_application = user.user_applications.build(name: 'name') }

  subject { @user_application }

  describe 'validations' do
    context 'when name is missing' do
      before { @user_application.name = '' }
      it { should_not be_valid }
    end

    context 'when user_id is missing' do
      before { @user_application.user_id = nil }
      it { should_not be_valid }
    end

    # other validations
  end
end

Upvotes: 1

Rustam Gasanov
Rustam Gasanov

Reputation: 15781

You should test validations/associations/fields existence/etc in corresponding specs. I don't see your UserApplication validations, but if I correctly understand you, your specs for this model should look like this(I am using shoulda and shoulda-matchers gems for testing):

require 'spec_helper'

describe UserApplication do
  let!(:user_application) { create(:user_application) }

  it { should have_many(:builds).dependent(:destroy) }
  it { should belong_to(:user) }
  it { should validate_presence_of(:name) }
end

I am always creating only the instance of the model I want to test. It is important to test that associations exist and correct, but you don't need to create testing model instance through association.

Upvotes: 1

Related Questions