我是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 ==)
答案 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
注意:
:aggregate_failures
选项。使用此选项,如果第一个期望失败,则还会执行下一个期望,考虑到在这种情况下,以下期望不依赖于第一个期望,可以使用超过1个期望的示例。{{ 3}} post
区块中创建expect
,您可以执行不同的操作:在发布帖子之前以及在您测试的帖子之后将列表的数量存储在变量中改变与否,也许你认为它会更清楚,它会在后台做同样的事情。