Rails rspec控制器测试返回一个未知的哈希值

时间:2016-05-13 18:27:34

标签: ruby-on-rails ruby-on-rails-4 rspec

我有一个非常简单的控制器,看起来像这样。

module Veterinarians
  module Dictionaries
    class SpecialitiesController < ApplicationController
      respond_to :json

      skip_before_action :check_current_vet, only: %i( index )

      def index
        @specialities = Veterinarians::Speciality.all
        respond_with(@specialities)
      end
    end
  end
end

我有一个看起来像这样的rspec控制器测试。

require 'rails_helper'

Rails.describe Veterinarians::Dictionaries::SpecialitiesController, type: :controller do
  # Not returning a response body in JSON when testing RSPEC (https://github.com/rails/jbuilder/issues/32)
  render_views true

  routes { Veterinarians::Engine.routes }

  let(:user) { double :user, id: 123 }
  before { sign_in(user) }

  context '#index' do
    let(:speciality) { double :speciality, id: :some_id, value: :some_val }

    before { allow(Veterinarians::Speciality).to receive(:all).and_return [speciality] }

    subject { get :index, format: :json }

    it { is_expected.to have_http_status(:ok) }
    it { expect(JSON.parse(subject.body)).to include('id' => 'some_id', 'value' => 'some_val') }
  end
end

第二个示例因此错误而失败。

expected [{"__expired" => false, "name" => "speciality"}] to include {"id" => "some_id", "value" => "some_val"}

任何关于为什么会失败的提示以及&#34; __过期&#34;来自哪里?

我还有其他测试使用相同的测试方法,这些测试都是成功的。

3 个答案:

答案 0 :(得分:1)

我怀疑这是来自RSpec的双重内部表示:

https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/test_double.rb#L10

RSpec的双打有时与Rails一起运行不佳。尝试实例化一个真实的Speciality实例,或使用像FactoryGirl这样的实例。

答案 1 :(得分:0)

Rails最终在双人座上调用library(Rsamtools) bam.dir <- c("folder1","folder2","folder3") for (dir in bam.dir) { bam_files <- list.files(path=dir, pattern="bam$", full.names=TRUE) new_file_name <- file.path(dir, "merged.bam") mergeBam(files=bam_files, destination=new_file_name) } 。您没有在double上存根该方法,因此调用了to_json方法rails添加到to_json

这个implementation只转储对象的实例变量,在这种情况下是test double的内部状态。

你可以在double上存根Object,虽然你的规范在那时不会测试很多。

答案 2 :(得分:0)

您应该使用工厂来创建测试数据。两个最受欢迎的是FactoryGirl或FactoryBot。

示例:

temp->next

FactoryGirl.define do factory :user do sequence(:email) { |n| "name#{n}@example.com" } password 'password' end end 会为每个用户创建不同的电子邮件。可以找到更多详细信息here