控制器与Rails中的请求规范。如何正确地做到这些?

时间:2017-03-01 14:25:11

标签: unit-testing ruby-on-rails-4

所以,我正在阅读的一个论点是,控制器测试应该是控制器的单元测试,而请求规范应该更多地是涉及路由器,控制器和控制器的集成测试。响应。这就是我工作的代码库中的哲学。鉴于这一点,考虑到我拥有这个控制器,这是编写这两个测试的最佳方法:

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

所以我的请求规范看起来像大多数人写的典型的集成控制器测试:

require 'rails_helper'

RSpec.describe "Wine API", type: :request do

  describe '#get /api/wine' do
    let!(:wine) { create(:wine) }
    subject { get "/api/wine_invite_beta/wine_tokens/:id", params }

    let(:params) {
      {
        id: wine.id
      }
    }

    context "and the wine exists" do
      it "returns back a JSON response of names" do
        subject

        expect(JSON.parse(response.body)).to eq("id" => wine.id, "varietal" => wine.varietal)
        expect(response).to have_http_status(:ok)
      end
    end

    context "and wine does not exist" do
      it "returns back a JSON response of errors" do
        subject

        expect(JSON.parse(response.body)).to eq("error" => { "message"    
       ....
       end
    end
  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之后检查控制器的状态。有谁知道怎么做?

更一般地说,人们如何看待这种方法来制作控制器与请求规范?

0 个答案:

没有答案