繁体   English   中英

仅请求规范第一个上下文是成功的

[英]Request spec only first context is success

我有一个请求规范,我想测试 CRUD。

问题是我首先提出的任何请求都会成功,但随后的 rest 会失败。 (意思是,在下面的情况下, GET会成功,但POST会失败。如果我切换 2 个上下文块, POST然后成功,然后GET失败)。

失败的测试表示响应是401 Unauthorized 我不确定是api_key突然变得无效还是什么。 或者和我分配给它的角色有关系。 (我为用户分配了一个 system_admin 角色,以便能够通过cancancan进行 CRUD)

使它全部工作的方法是,如果我将所有请求放在一个大的it块中(我认为这不是一个好习惯,因为它只返回 1 个通过的示例,而实际上我有超过 1 个。)

我也尝试在每个块中再次登录我的用户,但仍然发生同样的事情。

我是 RSpec 的新手,因此我们将不胜感激。 非常感谢!

require 'rails_helper'

RSpec.describe "Departments", type: :request do

    user = FactoryBot.build(:user)
    role = FactoryBot.build(:role, name: "system_admin")
    user.add_role(role.name)

    headers = { "x-app-api-key" => user.api_key }

    before do
      sign_in user
    end
  
  describe "CRUD /v1/departments" do

    context "GET" do
      it "called get" do
        get api_departments_path, headers: headers
 
        expect(response.content_type).to eq("application/json; charset=utf-8")
        expect(response).to have_http_status(:success)
      end
    end

    context "POST" do
      it "called post" do
        post api_departments_path, headers: headers, params: { name: "department" }

        expect(response.content_type).to eq("application/json; charset=utf-8")
        expect(response).to have_http_status(:success)
      end
    end
  end
end

这个规范有很多问题。 首先是使用局部变量而不是let/let! :

require 'rails_helper'

RSpec.describe "Departments", type: :request do
  user = FactoryBot.build(:user)
  role = FactoryBot.build(:role, name: "system_admin")
  user.add_role(role.name)

这样做的问题是这些变量将在 RSpec 设置规范时设置,而不是为每个示例设置。 因此,如果您确实将记录插入到数据库中,则在第一个示例运行后它们仍将被擦除,并且所有后续示例都将失败。

所以让我们解决这个问题:

require 'rails_helper'

RSpec.describe "Departments", type: :request do
  let(:user) { FactoryBot.create(:user) } 
  let(:role) { FactoryBot.create(:role, name: "system_admin") } 
  before do
    user.add_role(role.name)
  end

let每个示例评估一次,然后记忆。

请注意使用create而不是build将记录保存在数据库中,以便实际上可以从 controller 访问它。

那么问题是,除了测试 http 响应代码之外,这些测试实际上不提供任何值或描述您正在测试的应用程序的行为。

测试您的应用程序 - 而不是您的测试。 如果失败消息没有告诉您有关应用程序的哪一部分不工作的任何信息,那么测试几乎毫无价值。

require 'rails_helper'

RSpec.describe "Departments", type: :request do

  let(:user) { FactoryBot.create(:user) } 
  let(:role) { FactoryBot.create(:role, name: "system_admin") } 
  let(:headers) do 
    { "x-app-api-key" => user.api_key }
  end
  let(:json) { response.parsed_body }

  before do
    user.add_role(role.name)
    sign_in user  
  end

  describe "GET /v1/departments" do
    let(:departments) { FactoryBot.create_list(:department, 5) }
    it "responds with a list of the departments" do
      get api_departments_path, headers: headers
      expect(response).to be_successful
      # @todo ensure the JSON response contains the expected departments
    end
  end
  
  describe "POST /v1/departments" do
    context "with invalid parameters" do
      let(:params) { { name: "" } } # this should just be an invalid or incomplete set of attributes

      it "doesn't create a department" do
        expect do
          post api_departments_path, headers: headers, params: params
        end.to_not change(Department, :count)
        expect(response).to have_http_status(:unprocessable_entity)
      end 
    end

    context "with valid parameters" do
      let(:params) { FactoryBot.attributes_for(:department) }

      it "creates a department" do
        expect do
          post api_departments_path, headers: headers, params: params
        end.to change(Department, :count).by(1)
        expect(response).to have_http_status(:created)
        # @todo test that either a JSON representation is returned 
        # or that the response contains a location header with the URI 
        # to the resource
      end 
    end
  end
end

测试内容类型在很大程度上是多余的,因为您将内容类型设置为 API 应用程序的默认值,如果不返回application/json ,则测试 JSON 响应将失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM