Ben*_*enj 4 ruby-on-rails rspec2 ruby-on-rails-4
我正在努力保持我的spec文件尽可能干净.使用'shoulda'宝石并编写遵循相同模式的自定义匹配器.
我的问题是创建一个自定义匹配器,它将包装expect{ post :create ... }.to change(Model, :count).by(1)并可以与其他'shoulda'匹配器在相同的示例组中使用.详情如下:
自定义匹配器(简化)
RSpec::Matchers.define :create_a_new do |model|
match do |dummy|
::RSpec::Expectations::ExpectationTarget.new(subject).to change(model, :count).by(1)
end
end
Run Code Online (Sandbox Code Playgroud)
工作实例
describe 'POST create:' do
describe '(valid params)' do
subject { -> { post :create, model: agency_attributes } }
it { should create_a_new(Agency) }
end
end
Run Code Online (Sandbox Code Playgroud)
只要我使用subjectlambda并且我的匹配器是示例组中唯一的匹配器,这项工作就可以了.
失败的例子
失败的例子1
在同一组中添加更多示例会使另一个匹配器失败,因为subject现在是lambda而不是Controller的实例.
describe 'POST create:' do
describe '(valid params)' do
subject { -> { post :create, model: agency_attributes } }
it { should create_a_new(Agency) }
it { should redirect_to(Agency.last) }
end
end
Run Code Online (Sandbox Code Playgroud)
失败的例子2
'shoulda'匹配器希望我定义一个before块,但这与我的自定义匹配器不兼容
describe 'POST create:' do
describe '(valid params)' do
before { post :create, agency: agency_attributes }
it { should create_a_new(Agency) }
it { should redirect_to(Agency.last) }
end
end
Run Code Online (Sandbox Code Playgroud)
预期结果
我正在寻找一种方法来编写我的自定义匹配器,它与其他匹配器在同一个示例组中,这意味着我的自定义匹配器应该使用before块来执行控制器操作,上面的"失败的示例#2"是我的方式喜欢写我的规格.可能吗?
谢谢阅读
我不认为有一种方法可以让你失败的例子通过.
这是因为它change真的需要一个lambda,因为它需要执行两次计数(一次之前,一次调用之后).这就是我倾向于不使用它(或在上下文隔离中使用它)的原因.
我通常做的不是使用count匹配器,而是检查三件事:
@model,那么我使用expect(assigns(:model)).to be_persistedexpect(assigns(:model)).to be_a(Model).这就是我通常在change不使用它的情况下测试匹配器的方式.当然,您现在可以创建自己的匹配器
RSpec::Matchers.define :create_a_new do |model|
match do |actual|
actual.persisted? &&
actual.instance_of?(Participant) &&
(Participant.last == actual)
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |