【问题标题】:RSpec test not hitting view with render_viewRSpec 测试未使用 render_view 访问视图
【发布时间】:2017-08-05 11:05:02
【问题描述】:

我在使用 RSpec 测试 Rails 控制器中的索引操作和响应时收到此错误: JSON::ParserError: A JSON text must at least contain two octets!

最常见的修复——包括render_views——不起作用,nil 没有通过。测试没有命中视图。当我在控制器的索引操作中插入render json: {test: 'hello world'}, status: 200 and return,并在视图中(index.json.jbuilder)和测试中的get :index 之后进行撬动,我可以看到有一个响应体。如果我将测试期望修改为expect(response).to render_template '[]',我可以看到应该在响应正文中的空数组。为什么 render_views 失败了,我该如何让它再次工作?

这里是 index_spec.rb:

require 'rails_helper'

RSpec.describe ThingsController, type: :controller do
  render_views
  let(:json_response) { JSON.parse(response.body) }
  let(:status) { response.status }
  let(:user) { create(:user_with_associations) }
  subject{ ThingsController }

  describe "GET #index" do
    context "(success cases)" do
      before(:each) do
        expect_any_instance_of(subject).to receive(:set_user_by_token).and_return(user)
      end

    context "and when there are no things" do
      before(:each) do
        get :index
      end

      it "returns a 200 status" do
        expect(status).to eq 200
      end

      it "returns a top level key of data with an empty array" do
        expect(json_response["data"]).to eq []          
      end
    end
  end
end

这是 rails_helper.rb:

ENV["RAILS_ENV"] ||= 'test'
require_relative 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = true

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  config.infer_spec_type_from_file_location!
end

这里是 spec_helper.rb

ENV["RAILS_ENV"] ||= 'test'

require 'factory_girl_rails'
require 'faker'

include ActionDispatch::TestProcess

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end

  config.include FactoryGirl::Syntax::Methods

  config.before do
    FactoryGirl.factories.clear
    FactoryGirl.find_definitions
  end
end

这是正在测试的控制器动作 things_controller.rb:

class ThingsController < ApplicationController

  before_action :authenticate_user!, only: [ :index ]
  before_action -> {check_last_updated("Thing")}, only: [ :index ]

  def index
    @things = @current_user.things.in_last_three_months.approved_and_unapproved.order(start_time: :asc)
  end
end

导轨 4.2.0 红宝石 2.1.2 RSpec 3.5.4

这是我在这里的第一个问题,因此请告诉我是否应该包含其他信息。

【问题讨论】:

    标签: ruby-on-rails json ruby rspec


    【解决方案1】:

    您没有正确地在规范中排除身份验证。你说

    expect_any_instance_of(subject).to receive(:set_user_by_token).and_return(user)
    

    但你应该说

    allow_any_instance_of(subject).to receive(:set_user_by_token).and_return(user)
    

    作为一般规则,应尽可能避免使用*_any_instance_of 方法,因为they can be ambiguous 在更细微的情况下。在控制器规范中,您可以使用controller 访问正在测试的控制器实例。例如

    allow(controller).to receive(:set_user_by_token).and_return(user)
    

    【讨论】:

      猜你喜欢
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      • 2015-11-28
      • 2015-12-22
      • 2011-06-28
      相关资源
      最近更新 更多