【发布时间】:2017-06-16 20:42:00
【问题描述】:
我对控制器规范中的每个 HTTP 方法/控制器操作组合重复了一次以下测试:
it "requires authentication" do
get :show, id: project.id
# Unauthenticated users should be redirected to the login page
expect(response).to redirect_to new_user_session_path
end
我找到了以下三种方法来重构它并消除重复。哪个最合适?
共享示例
在我看来,共享示例是最合适的解决方案。但是,为了将params 传递给共享示例,必须使用块感觉有点尴尬。
shared_examples "requires authentication" do |http_method, action|
it "requires authentication" do
process(action, http_method.to_s, params)
expect(response).to redirect_to new_user_session_path
end
end
RSpec.describe ProjectsController, type: :controller do
describe "GET show", :focus do
let(:project) { Project.create(name: "Project Rigpa") }
include_examples "requires authentication", :GET, :show do
let(:params) { {id: project.id} }
end
end
end
辅助方法
这具有不需要块将project.id 传递给辅助方法的优点。
RSpec.describe ProjectsController, type: :controller do
def require_authentication(http_method, action, params)
process(action, http_method.to_s, params)
expect(response).to redirect_to new_user_session_path
end
describe "GET show", :focus do
let(:project) { Project.create(name: "Project Rigpa") }
it "requires authentication" do
require_authentication(:GET, :show, id: project.id )
end
end
end
自定义匹配器
如果有单行测试就好了。
RSpec::Matchers.define :require_authentication do |http_method, action, params|
match do
process(action, http_method.to_s, params)
expect(response).to redirect_to Rails.application.routes.url_helpers.new_user_session_path
end
end
RSpec.describe ProjectsController, type: :controller do
describe "GET show", :focus do
let(:project) { Project.create(name: "Project Rigpa") }
it { is_expected.to require_authentication(:GET, :show, {id: project.id}) }
end
end
提前致谢。
【问题讨论】:
-
我相信您可以将辅助方法移动到 /support/helpers 并通过包含在您的其他控制器中利用它们。自定义匹配器可能是 rspec 方式,但谁在乎它是否适合你
-
我喜欢循序渐进的方法,所以可能先使用辅助方法,当我在其他地方看到它有用时,再将其重构为自定义匹配器
标签: ruby-on-rails ruby rspec rspec-rails