如何使用Rspec测试关联模型

时间:2014-03-16 17:17:01

标签: ruby-on-rails ruby rspec devise

在我的应用程序中,我有以下模型:

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


class Build < ActiveRecord::Base
  belongs_to :user_application
end

用户模型由 Devise 生成。

我的问题是:我想测试模型验证,我是否应该这样做:

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

或者我应该通过用户创建 UserApplication ?一般来说,在测试我的模型时,我是否应该记住关联,如果测试示例与关系无关?

2 个答案:

答案 0 :(得分:1)

您应该在相应的规范中测试验证/关联/字段存在/ etc。我没有看到您的UserApplication验证,但如果我正确理解您,您对此模型的规范应如下所示(我使用shouldashoulda-matchers宝石进行测试) :

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

我总是只创建我想要测试的模型的实例。测试关联是否存在和正确非常重要,但您不需要通过关联创建测试模型实例。

答案 1 :(得分:1)

尽可能使测试代码并行应用程序代码似乎是谨慎的。也就是说,如果UserApplication将通过控制器中的User创建,则应该在测试中以相同的方式完成。此外,您的UserApplication验证可能迟早会测试该关联,因此应以有效的方式创建测试主题。考虑到这一点,您可以按如下方式设置测试:

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