【问题标题】:RSpec how to properly structure tests?RSpec如何正确构建测试?
【发布时间】:2015-03-10 11:28:58
【问题描述】:

我正在使用带有 REST API 的 Rails 编写应用程序。除非用户已获得授权,否则大多数控制器都无法访问。这是通过在控制器中的before_action 挂钩中插入一个检查用户权限的方法来完成的。我想测试未经授权的用户无法访问 API 的某些部分。目前我是这样做的:

需要'rails_helper'

RSpec.describe RoomsController, type: :controller do
  ...
  describe "while unauthenticated" do
    before do
      logout
    end

    def expect_unauth
      expect(response).to have_http_status(:unauthorized)
    end

    it "GET #index returns http unauthorized" do get :index; expect_unauth end
    it "GET #show returns http unauthorized" do get :show, {id: 1}; expect_unauth end
    it "DELETE #destroy returns http unauthorized" do delete :destroy, {id: 1}; expect_unauth end
    it "POST #create returns http unauthorized" do post :create, {id: 1}; expect_unauth end
    it "PUT #update returns http unauthorized" do put :update, {id: 1}; expect_unauth end
  end

它可以工作,但对于每个控制器来说几乎都是一样的。如何在不将这段代码复制粘贴到每个控制器中的情况下进行这样的测试?我是否应该对其进行测试,或者因为它非常简单,我应该假设它可以工作并为特定于控制器功能的特定功能编写测试?

另外,它甚至属于控制器规格吗?也许它应该是一个请求规范?

【问题讨论】:

  • Rspec 有一个称为共享示例的功能。也许这就是你要找的东西:relishapp.com/rspec/rspec-core/docs/example-groups/…
  • 如果我有时间我会为此创建自定义匹配器。在此处阅读如何执行此操作:relishapp.com/rspec/rspec-expectations/v/2-4/docs/…。理想情况下,我希望它阅读it { should require_login } 以了解控制器上定义的所有操作,或者如果控制器部分公开,则阅读it { should require_login.for(:edit)。这是一项艰巨的任务(但绝对可行),所以玩得开心。 :)

标签: ruby-on-rails ruby-on-rails-3 unit-testing ruby-on-rails-4 rspec


【解决方案1】:

我通常有相同行为的代码:

ACTIONS = [
  [ :index, :get, {} ],
  [ :show, :get, { :id => 1 }],
  [ :delete, :destroy, { :id => 1 }]
]

ACTIONS.each do |action, method, params|
  it "shout return unauthorized when #{method} #{action}" do
    send(method, action, params)
    expect_unauth
  end
end

【讨论】:

  • 然后复制粘贴到每个控制器上?一定有更好的方法
  • @user860478 不是真的,我在spec_helper.rb 中声明了一个check_unauthorized 方法,然后像check_unauthorizes([ :index, :get .... ]) 这样在我的模型中调用它。
【解决方案2】:

为什么需要在每个控制器操作上测试 expect_unauth?

我假设您在 ApplicationController 或所有控制器共有的某个地方进行了身份验证检查。即,当存在未经授权的访问时,所有需要身份验证的 API 操作都以相同的方式响应。所以,在每一个动作上测试它是多余的。您可以编写一个规范来测试对系统的未经授权的访问是否按预期响应。

在测试操作功能的示例中,系统首先检查以确保存在有效登录,如果没有,则测试中的下一个期望将失败。

要回答您应该使用控制器规格还是请求规格的问题,请查看rspec_api_documentation。它将请求规范与文档生成器结合在一起。

如果这对您来说太过分了,那么我认为对于 API 测试,它是控制器规范和请求规范之间的一条细线。控制器规范存根视图,因此如果您想检查实际响应中的某些内容,例如 JSON 中是否包含特定内容,那么您将使用请求规范。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2023-03-18
    • 1970-01-01
    相关资源
    最近更新 更多