条件码if-else的Rspec?

时间:2017-11-30 02:37:00

标签: ruby-on-rails node.js ruby testing rspec

我是RSpec的新手,但在这里我正在尝试基于此代码创建测试,并且我一直在收到此错误。有什么建议吗? 代码:

  serialization_scope nil
  before_action :set_list, only: [:show, :destroy, :update]
  before_action :verify_user, only: :show


  def create
    @list = current_user.lists.build(list_params)

    if @list.save

      render json: {message: ['Success']}, status: 200
    else
      render json: {errors:[@list.errors.full_messages]}, status: 400
    end
  end

这是我开始的RSpec文件:

require "rails_helper"

RSpec.describe V1::ListsController, :type => :controller do

  describe "POST create" do
    it "returns HTTP status" do
      expect(post :create).to change(@list, :count).by(+1)
      expect(response).to have_http_status :success #200
    end
  end

  describe 'GET status if its not created' do
    it "return HTTP status - reports BAD REQUEST (HTTP status 400)" do
      expect(response.status).to eq 400
    end
  end
end

我得到的错误是:

Failures:

  1) V1::ListsController GET status if its created returns HTTP status
     Failure/Error: expect(post :create).to change(@list, :count).by(+1)
       expected #count to have changed by 1, but was not given a block
     # ./spec/controllers/lists_controller_spec.rb:8:in `block (3 levels) in <top (required)>'

  2) GET status if its not created return HTTP status - reports BAD REQUEST (HTTP status 400)
     Failure/Error: expect(response.status).to eq 400

       expected: 400
            got: 200

       (compared using ==)

4 个答案:

答案 0 :(得分:2)

试试这段代码。

require 'rails_helper'

RSpec.describe V1::ListsController, type: :request do
  describe 'valid request' do
    it 'returns HTTP status' do
      post '/list', params: { list: { list_name: 'xyz' } }
      expect(response.status).to eq 201
    end
  end
  describe 'invalid request' do
      it "should return unauthorized" do
        post '/list'
        assert_response :unauthorized
      end
    end
end

在params中,您需要传递list_params

答案 1 :(得分:1)

Spec看起来像:

var fromCMS = 'MSRP Base Price †';
var superLabel = '<sup>' + fromCMS.replace('MSRP Base Price', '').trim() + '</sup>';

干杯!

答案 2 :(得分:0)

您可以通过故意导致某些验证失败来测试未创建的对象,例如您可以从RSpec传递强制属性nil

示例请求:post :create, { title: nil }

但根据您的RSpec代码,List模型似乎没有验证。因此,让我们尝试存根save并返回false进行此特定测试。

describe 'GET status if its not created' do
  # Assuming your model name is `List`
  before { allow_any_instance_of(List).to receive(:save) { false } }
  it "return HTTP status - reports BAD REQUEST (HTTP status 400)" do
    post :create
    expect(response.status).to eq 400
  end
end

请发布list的模型,我可以通过更合适的测试更新答案。

答案 3 :(得分:0)

Ishika,让我看看我是否可以帮助你:)。

RSpec官方文档建议您使用请求规范而不是控制器规范。这是推荐的,因为Rails 5弃用了控制器测试中使用的一些方法。您可以阅读有关此here at RSpec blog

的更多信息

ps。到目前为止,您可以使用控制器测试,但在未来的主要版本的RSpec中可以弃用它。

我在代码后留下了一些注意事项,请同时阅读。

我会写一个这样的请求规范:

# spec/requests/v1/lists_controller_create_spec.rb

require "rails_helper"

RSpec.describe V1::ListsController do
  describe 'success' do
    it 'returns ok and creates a list', :aggregate_failures do # :aggregate_failures is available only for RSpec 3.3+
      expect do
        post '/list', title: 'foo' # This will also test your route, avoiding routing specs to be necessary
      end.to change { List.count }.from(0).to(1)

      expect(response).to have_http_status(:ok)
    end
  end

  describe 'bad request' do
    before do
      # This is needed because your controller is not validating the object, but look at my
      # comment below (out of the code), to think about this behavior, please.
      allow_any_instance_of(List).to receive(:save).and_return(false) 
    end

    it 'returns a bad request and does not create a list' do
      expect do
        post '/list', title: 'foo' # This will also test your route, avoiding routing specs to be necessary
      end.not_to change { List.count }

      expect(response).to have_http_status(:bad_request)
    end
  end 
end

注意:

  1. 我建议通过示例使用超过1个期望,这在本规范中是正确的,因为它们很简单,因为我使用:aggregate_failures选项。使用此选项,如果第一个期望失败,则还会执行下一个期望,考虑到在这种情况下,以下期望不依赖于第一个期望,可以使用超过1个期望的示例。{{ 3}}
  2. 如果未保存对象,但您没有验证它,则返回错误请求。如果您的模型具有验证对象的验证,请调整规格以使保存失败(而不是使用我使用的模拟)并考虑在响应中呈现错误消息
  3. 如果您认为在post区块中创建expect,您可以执行不同的操作:在发布帖子之前以及在您测试的帖子之后将列表的数量存储在变量中改变与否,也许你认为它会更清楚,它会在后台做同样的事情。