正如标题所暗示的那样,我只是尝试使用rSpec在API控制器中测试创建操作。控制器看起来像:
lib1/__init__.py
现在,这正是应该做的应该是伟大的。然而,测试......并非如此。这是我对测试部分所拥有的:
module Api
module V1
class BathroomController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:create]`
def create
bathroom = Bathroom.new(bathroom_params)
bathroom.user = current_user
if bathroom.save
render json: { status: 'SUCCESS', message: 'Saved new bathroom', bathrooms: bathroom }, status: :ok
end
end
private
def bathroom_params
params.require(:bathroom).permit(:establishment, :address, :city, :state, :zip, :gender, :key_needed, :toilet_quantity)
end
end
end
end
我确定这里不止一件事是错的,但我很难找到有关正确测试方法的大量信息。任何见解或建议将不胜感激。
答案 0 :(得分:2)
我会跳过控制器规格altogther。 Rails 5几乎委托ActionController::TestCase
(RSpec包装为控制器规格)到垃圾抽屉。控制器测试不会发送真正的http请求,并将路由器和中间件等Rails的关键部分存根。很快就会发生彻底的贬值和授予单独的宝石。
相反,您想要使用请求规范。
RSpec.describe "API V1 Bathrooms", type: 'request' do
describe "POST /api/v1/bathrooms" do
context "with valid parameters" do
let(:valid_params) do
{
bathroom: {
establishment: "Fake Place",
address: "123 Main St",
city: "Cityton",
state: "NY",
zip: "11111",
gender: "Unisex",
key_needed: false,
toilet_quantity: 1
}
}
end
it "creates a new bathroom" do
expect { post "/api/v1/bathrooms", params: valid_params }.to change(Bathroom, :count).by(+1)
expect(response).to have_http_status :created
expect(response.headers['Location']).to eq api_v1_bathroom_url(Bathroom.last)
end
it "creates a bathroom with the correct attributes" do
post "/api/v1/bathrooms", params: valid_params
expect(Bathroom.last).to have_attributes valid_params[:bathroom]
end
end
context "with invalid parameters" do
# testing for validation failures is just as important!
# ...
end
end
end
同样发送一堆像render json: { status: 'SUCCESS', message: 'Saved new bathroom', bathrooms: bathroom }, status: :ok
这样的垃圾是反模式。
作为回应,您应该发送201 CREATED响应,其中包含一个包含新创建资源的URL或包含新创建资源的响应主体的位置标题。
def create
bathroom = current_user.bathrooms.new(bathroom_params)
if bathroom.save
head :created, location: api_v1_bathroom_url(bathroom)
else
head :unprocessable_entity
end
end
如果您的客户无法通过查看响应代码来判断响应是否成功,那么您做错了。
答案 1 :(得分:1)
您真的不需要测试数据库中保存的记录中的值,您可以执行以下操作:
expect(post :create, params: params).to change(Bathroom, :count).by(1)
足以测试创建操作在所需的表上创建记录。
然后你可以添加更多规格来测试Bath.new是否接收到预期的参数(这样你就知道保存时会有那些字段),或者存根浴室对象以及它的保存方法来测试响应。
如果你想测试保存的记录是否具有正确的值,我认为规范属于浴室模型而不是控制器(或者更好,是集成测试)。
答案 2 :(得分:0)
所以我遵循了max的建议,但做了一点改动让它运转起来。我的最终代码是:
c:\Python36>pip install os
Collecting os
Using cached os-0.5.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "c:\python36\lib\tokenize.py", line 452, in open
buffer = _builtin_open(filename, 'rb')
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\swideb\\AppData\\Local\\Temp\\pip-build-_g65v8sr\\os\\setup.py'
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\swideb\AppData\Local\Temp\pip-build-_g65v8sr\os\
c:\Python36>
关键是使用FactoryGirl创建新用户,因为浴室需要关联的user_id才有效。