2017-03-14 84 views
0

我收到此錯誤使用RSpec的測試在Rails控制器的索引動作和反應時: JSON::ParserError: A JSON text must at least contain two octets!RSpec的測試不打觀點與render_view

最常見的修復 - 包括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 

的Rails 4.2.0 的Ruby 2.1.2 的RSpec 3.5.4

這是我的第一個問題在這裏,所以讓我知道,如果有應包含的其他信息。

回答

2

你在規範中沒有正確地認證認證。你說

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)