RSpec&轮胎宝石:测试轮胎::结果::集合

时间:2012-09-11 20:39:41

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

尝试理解Tire gem周围的语法。

此控制器规范(来自脚手架模板的默认值)失败

  describe "GET index" do
    it "assigns all reports as @reports" do
      report = Report.create! valid_attributes
      get :index, {}, valid_session
      assigns(:reports).should eq([report])
    end
  end

,因为

 Failure/Error: assigns(:reports).should eq([report])
 TypeError:
   can't convert Tire::Results::Collection to Array (Tire::Results::Collection#to_ary gives Tire::Results::Collection)

如何编写规范以便它需要Tire 结果集合而不是活动记录对象数组?或者,有更好的方法来解决这个问题吗?

FWIW -

class ReportsController < ApplicationController  
  def index
    @reports = Report.search(params)
  end

  ...

和模型:

class Report < ActiveRecord::Base
  include Tire::Model::Search
  include Tire::Model::Callbacks
  ...
  def self.search(params)
    tire.search(load: true) do
      query { string params[:query] } if params[:query].present?
    end
  end
  ...

1 个答案:

答案 0 :(得分:2)

我意识到这是一个非常迟到的答案,但是,嘿,这就是。

Rspec正在进行直接比较。它有一个集合,它试图将它与数组进行比较。但是,Tire将数组定义为不实际返回一个数组(为什么,我不确定,这对我来说很烦人!)

鉴于你不打算比较数组,我快速浏览了Collection的来源:https://github.com/karmi/tire/blob/master/lib/tire/results/collection.rb

好吧,我们没有一个有用的to_ary ......但我们确实有一个,并且包含了Enumerable。这意味着我们基本上拥有数组可用的所有内容。

所以,鉴于此,我们在这里真正想做什么?我们想检查@reports中是否有@report。好吧,我们有可枚举的,快速检查期望来源(https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/built_in/include.rb#L38)说包括将映射到包括?在arrayesque对象上。

因此,简而言之,请尝试将测试更改为:

describe "GET index" do
  it "assigns all reports as @reports" do
   report = Report.create! valid_attributes
   get :index, {}, valid_session
   assigns(:reports).should include(report)
  end
end