我正在努力保持我的规范文件尽可能干净。使用 'should' gem 并编写遵循相同模式的自定义匹配器。
我的问题是关于创建一个自定义匹配器,该匹配器可以包装expect{ post :create ... }.to change(Model, :count).by(1)
并可以在与其他“应该”匹配器相同的示例组中使用。详情如下:
自定义匹配器(简化)
RSpec::Matchers.define :create_a_new do |model|
match do |dummy|
::RSpec::Expectations::ExpectationTarget.new(subject).to change(model, :count).by(1)
end
end
工作示例
describe 'POST create:' do
describe '(valid params)' do
subject { -> { post :create, model: agency_attributes } }
it { should create_a_new(Agency) }
end
end
只要我使用subject
lambda 并且我的匹配器是示例组中唯一的匹配器,这项工作就可以了。
失败的例子
失败示例 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
失败示例 2
“应该”匹配器希望我定义一个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
预期结果
我正在寻找一种方法来编写我的自定义匹配器,该匹配器将适合与其他匹配器相同的示例组,这意味着我的自定义匹配器应该使用该before
块来执行控制器操作,上面的“失败示例 #2”是我想要的方式喜欢写我的规格。可能吗?
谢谢阅读