Unit testing Rails中的控制器与请求规格。如何正确处理它们?
因此,我正在阅读的一个论点是,控制器测试应该是控制器的单元测试,请求规范应该更多地是一个集成测试,涉及路由器、控制器和响应。这就是我工作的代码库中的哲学。鉴于此,如果我有这个控制器,那么编写这两个测试的最佳方法是什么:Unit testing Rails中的控制器与请求规格。如何正确处理它们?,unit-testing,ruby-on-rails-4,Unit Testing,Ruby On Rails 4,因此,我正在阅读的一个论点是,控制器测试应该是控制器的单元测试,请求规范应该更多地是一个集成测试,涉及路由器、控制器和响应。这就是我工作的代码库中的哲学。鉴于此,如果我有这个控制器,那么编写这两个测试的最佳方法是什么: class Api::WineController < ApplicationController def show wine = Wine.find(params[:id]) render json: { id: wine.id, varietal
class Api::WineController < ApplicationController
def show
wine = Wine.find(params[:id])
render json: { id: wine.id, varietal: wine.varietal }, status: :ok
rescue ActiveRecord::RecordNotFound
render json: { error: { message: "Wine not found") } }, status: :bad_request
end
end
因此,请求规范使用http方法(:get是使用的方法)来命中路由器,然后路由器命中控制器。这看起来更像是一个集成测试
控制器测试应该不用路由器,只测试类及其方法,就像我测试模型一样。是这样吗?人们同意吗?我就是这样写的:
require 'rails_helper'
RSpec.describe Api::WinesController, type: :controller do
describe "#show" do
let(:controller_instance) { described_class.new }
subject { controller_instance.show }
before do
allow(controller_instance).to receive(:params) { params }
end
let(:params) { { id: 1} }
context "and wine token exists for user" do
let!(:wine) { create(:wine) }
it "calls render with the wine token data" do
expect(controller_instance).to receive(:render).with(
json: {
id: wine.id,
varietal: wine.varietal
},
status: :ok
)
subject
end
end
可以吗?我只是设置一个期望,即在控制器中调用一个方法,因为这看起来像是一个命令。但这感觉不对。render
方法看起来更像是一个查询,而不是一个命令,因此我可能应该在调用render后检查控制器的状态。有人知道怎么做吗
更一般地说,人们对这种制作控制器和请求规格的方法有什么看法?Me,我不在乎控制器规格。95%的控制器操作是两行:“调用某个对象并呈现响应”。那个物体是分开测试的。控制器本身没有什么可测试的。有趣的是,我也经常听到它。哪本书有这样的建议?
require 'rails_helper'
RSpec.describe Api::WinesController, type: :controller do
describe "#show" do
let(:controller_instance) { described_class.new }
subject { controller_instance.show }
before do
allow(controller_instance).to receive(:params) { params }
end
let(:params) { { id: 1} }
context "and wine token exists for user" do
let!(:wine) { create(:wine) }
it "calls render with the wine token data" do
expect(controller_instance).to receive(:render).with(
json: {
id: wine.id,
varietal: wine.varietal
},
status: :ok
)
subject
end
end