使用fixture返回rspec测试中的重复代码

时间:2015-12-21 16:20:43

标签: ruby rspec

我使用Rspec和fixture来测试Rails模型。

一些测试用例具有非常相似的代码,如下所示

it 'creates request' do
  u = users(:user_one)
  o = documents(:document_one)
  requests = Request.where(status: Request::PENDING, user: u, document: o) 
  expect { o.request_access(u) }.to change { requests.count }.by(1)    
end

it 'does not create a request if user already has access' do
  u = users(:user_one)
  o = documents(:document_one)
  Request.create status: Request::ACCEPTED, user: u, document: 0
  requests = Request.where(status: Request::PENDING, user: u, document: o) 
  expect { o.request_access(u) }.not_to change { requests.count }    
end

我怎样才能消除代码重复?有没有办法使用let来解决问题?如果我有更多的测试用例使用其他灯具并因此Request.where(status: Request::PENDING, user: u, document: o)引用其他对象怎么办?

2 个答案:

答案 0 :(得分:4)

这应该足够干。 let所有的事情!

let(:user) { users(:user_one) }
let(:document) { documents(:document_one) }
let(:requests) { Request.where(status: Request::PENDING, user: user, document: document) }
let(:action) { document.request_access(user) }

context 'user does not have access' do
  it 'creates request' do
    expect { action }.to change { requests.count }.by(1)    
  end
end

context 'user has approved access' do
  before do 
    Request.create status: Request::ACCEPTED, user: user, document: document
  end

  it 'does not create a request' do
    expect { action }.not_to change { requests.count }    
  end
end

答案 1 :(得分:1)

您可以使用letbefore(:each)

before(:each) do
  @u = users(:user_one)
  @o = documents(:document_one)
end

it 'creates request' do
  requests = Request.where(status: Request::PENDING, user: @u, document: @o) 
  expect { @o.request_access(@u) }.to change { requests.count }.by(1)    
end

it 'does not create a request if user already has access' do
  Request.create status: Request::ACCEPTED, user: @u, document: @o
  requests = Request.where(status: Request::PENDING, user: @u, document: @o) 
  expect { @o.request_access(@u) }.not_to change { requests.count }    
end
let(:u) { users(:user_one) }
let(:o) { documents(:document_one) }

it 'creates request' do
  requests = Request.where(status: Request::PENDING, user: u, document: o) 
  expect { o.request_access(u) }.to change { requests.count }.by(1)    
end

it 'does not create a request if user already has access' do
  Request.create status: Request::ACCEPTED, user: u, document: o
  requests = Request.where(status: Request::PENDING, user: u, document: o) 
  expect { o.request_access(u) }.not_to change { requests.count }    
end

编辑:您无法将requests查询添加到之前的过滤器,因为在第二次测试中您的查询之前有Request.create。无论如何,要干它,你可以创建一个返回查询的方法:

let(:u) { users(:user_one) }
let(:o) { documents(:document_one) }

it 'creates request' do
  requests 
  expect { o.request_access(u) }.to change { requests.count }.by(1)    
end

it 'does not create a request if user already has access' do
  Request.create status: Request::ACCEPTED, user: u, document: o
  requests 
  expect { o.request_access(u) }.not_to change { requests.count }    
end

def requests
  Request.where(status: Request::PENDING, user: u, document: o)
end