Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用夹具删除rspec测试中的重复代码_Ruby_Rspec - Fatal编程技术网

Ruby 使用夹具删除rspec测试中的重复代码

Ruby 使用夹具删除rspec测试中的重复代码,ruby,rspec,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 { reque

我使用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::PENDING,user:u,document:o)
指的是其他对象?

您可以使用
let
before(:each)



编辑:无法将
请求
查询添加到before筛选器,因为您有一个
请求。请在第二个测试中的查询之前创建
。无论如何,要使其干燥,您可以创建一个返回查询的方法:

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

您可以在(:each)
之前使用
let



编辑:无法将
请求
查询添加到before筛选器,因为您有一个
请求。请在第二个测试中的查询之前创建
。无论如何,要使其干燥,您可以创建一个返回查询的方法:

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

这应该足够干了<代码>让
所有的东西

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

这应该足够干了<代码>让
所有的东西

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

我真的想删除
requests=Request.where(状态:Request::PENDING,用户:u,文档:o)
。有办法吗?问题在于
请求。在请求查询之前创建需要调用的
,因此不能将其添加到(:each)
之前的
。。。如果您有
请求,请注意我编辑的回答。在一个before操作中创建
,它将在两个测试中运行。因此,除非您在Sergio answerI真正想要删除
requests=Request.where(状态:Request::PENDING,user:u,document:o)这样的上下文中包装测试,否则您的第一个测试将失败。有办法吗?问题在于
请求。在请求查询之前创建需要调用的
,因此不能将其添加到(:each)
之前的
。。。如果您有
请求,请注意我编辑的回答。在一个before操作中创建
,它将在两个测试中运行。因此,除非您将测试包装在Sergio Answer之类的上下文中,否则您的第一次测试将失败太好了,谢谢。出于某种原因,我认为不能在其他
let
块中使用
let
块。对于
:动作
,使用
主题
不是更清楚吗?@S.S.J:不知道。从不喜欢
主题
。除此之外,它暗示了一些对象,而这里我们有一个动作。但你想怎么说就怎么说。:)样式不同,但通常不鼓励使用显式
主题
,除非您正在编写共享方法。理想情况下,通过阅读测试,主题应该是显而易见的。太好了,谢谢。出于某种原因,我认为不能在其他
let
块中使用
let
块。对于
:动作
,使用
主题
不是更清楚吗?@S.S.J:不知道。从不喜欢
主题
。除此之外,它暗示了一些对象,而这里我们有一个动作。但你想怎么说就怎么说。:)样式不同,但通常不鼓励使用显式
主题
,除非您正在编写共享方法。理想情况下,通过阅读测试,受试者应该是显而易见的。