如何访问实例变量以测试规范中的“ receive”?

时间:2019-03-05 00:34:59

标签: ruby-on-rails rspec

我有以下规范片段:

  it 'should create company and user' do
    company_iv = assigns(:company)
    user_iv = assigns(:user)
    expect(subject).to receive(:create_timeline_event).with(company_iv, user_iv)
    expect { post :create, params }.to change { User.count }.by(1).and change { Company.count }.by(1)

,传统上使用接收语法来测试调用方法。我通常在调用上面片段中的发布之前调用它。我将如何访问该规范的用户和公司的实例变量?

1 个答案:

答案 0 :(得分:0)

看起来您正在尝试将几个不同的测试放入单个it语句中。这是我的处理方法:

it 'creates company and user' do
  expect { post :create, params }
    .to change { User.count }.by(1)
    .and change { Company.count }.by(1)
end

it 'assigns instance variables' do
  post :create, params

  expect(assigns(:company)).to eq(Company.last)
  expect(assigns(:user)).to eq(User.last)
end

it 'calls create_timeline_event with newly created company and user' do
  allow(some_object).to receive(:create_timeline_event)

  post :create, params

  expect(some_object)
    .to have_received(:create_timeline_event)
    .with(Company.last, User.last)
end

请注意,由于这些测试命中了数据库,因此测试速度将会很慢。另一种方法是使用模拟。看起来像这样:

let(:params) { ... }
let(:company) { instance_double(Company) }
let(:user) { instance_double(User) }

before do 
  allow(Company).to receive(:create).and_return(company)
  allow(User).to receive(:create).and_return(user)
  allow(some_object).to receive(:create_timeline_event)

  post :create, params
end

it 'creates company and user' do
  expect(Company).to have_received(:create).with(company_params)
  expect(User).to have_received(:create).with(user_params)
end

it 'assigns instance variables' do 
  expect(assigns(:company)).to eq(company)
  expect(assigns(:user)).to eq(user)
end

it 'calls create_timeline_event with newly created company and user' do
  expect(some_object)
    .to have_received(:create_timeline_event)
    .with(company, user)
end

这些测试根本不会访问数据库,这意味着它们将执行得更快。