简体   繁体   中英

RSpec: invalid model with searchkick

I'm not very sure I'm doing it right, but I have two models: House that has_one Address .

The Address model has:

class Address < ApplicationRecord
  searchkick
  belongs_to :house
end

I'm trying to test my house_controller with RSpec like this

RSpec.describe HousesController do
 context 'GET #index' do
 before { get :index }
 it     { is_expected.to render_template('index') }

 it 'assigns @houses' do
  h = create(:house)
  expect(assigns(:houses).results).to eq([h])
end
...

Nevertheless I always get a result which is not the one I expect. The code of my controller is the following:

def index
 if params[:term].present?
  @houses = House.search(params[:term])
 else
  @houses = House.search('*')
 end
end

I'm not sure I understand it, but could it be that since I'm using FactoryBot , it is creating lots of houses, and then when getting in the index method, there's a bunch of houses there and not only and precisely h ?

This is my failure:

Failures:

  1) HousesController GET #index assigns @houses
     Failure/Error: expect(assigns(:houses).results).to eq([h])

       expected: [#<House id: 763, rent: 1173, deposit: 739, description: "Rerum cado curso curo alias.", preferred_ge...2018-11-26 21:40:43", available_at: "2018-12-17", user_id: 15945, lease_length: nil, built_in: nil>]
            got: [#<House id: 215, rent: 0.839e3, deposit: 0.797e3, description: "Rerum aeneus taceo crepusculum aestu...2018-11-26 21:17:53", available_at: "2018-12-17", user_id: 15776, lease_length: nil, built_in: nil>]

       (compared using ==)

       Diff:
       @@ -1,2 +1,5 @@
       -[#<House id: 763, rent: 1173, deposit: 739, description: "Rerum cado curso curo alias.", preferred_gender: 0, created_at: "2018-11-26 21:40:43", updated_at: "2018-11-26 21:40:43", available_at: "2018-12-17", user_id: 15945, lease_length: nil, built_in: nil>]
       +[#<House id: 215, rent: 0.839e3, deposit: 0.797e3, description: "Rerum aeneus taceo crepusculum aestus.", preferred_gender: 0, created_at: "2018-11-25 12:50:11", updated_at: "2018-11-25 12:50:11", available_at: "2018-12-16", user_id: 8065, lease_length: nil, built_in: nil>,
       + #<House id: 235, rent: 0.519e3, deposit: 0.642e3, description: "Cicuta totidem arbustum arcesso fugit tego.", preferred_gender: 0, created_at: "2018-11-25 12:54:28", updated_at: "2018-11-25 12:54:28", available_at: "2018-12-16", user_id: 8085, lease_length: nil, built_in: nil>,
       + #<House id: 648, rent: 0.668e3, deposit: 0.1104e4, description: "Corporis tametsi demens.", preferred_gender: 0, created_at: "2018-11-26 21:17:43", updated_at: "2018-11-26 21:17:43", available_at: "2018-12-17", user_id: 15775, lease_length: nil, built_in: nil>,
       + #<House id: 649, rent: 0.799e3, deposit: 0.611e3, description: "Ut ancilla tredecim.", preferred_gender: 0, created_at: "2018-11-26 21:17:53", updated_at: "2018-11-26 21:17:53", available_at: "2018-12-17", user_id: 15776, lease_length: nil, built_in: nil>]

     # ./spec/controllers/houses_controller_spec.rb:12:in `block (3 levels) in <top (required)>'

I'm starting with RSpec now and it's really taking me effort and hours to try to grab the grasp of it, thanks a lot in advance!

Try creating your house in the before block:

context 'GET #index' do
  before do
    let!(:house) { create(:house) }
    get :index
  end

  it { is_expected.to render_template('index') }

  it 'assigns @houses' do
    expect(assigns(:houses).results).to eq([house])
  end
end

A couple of things to note:

  1. As opposed to let , let! is immediately invoked (thus creating your record before the index action is hit)
  2. Add a breakpoint (IDE) or use a debugger (byebug, pry, etc.) and put it before the get :index call to see what (if any) houses already exist.

Searchkick docs about disabling indexing for tests with RSpec.

You don't want to be updating your objects in Elasticsearch always while running tests. You want to do it only when you'll be explicitly testing your search functionality (or indexing/deleting from index). To do so, you will have to disable searchkick callbacks, define a custom tag for your tests and enable indexing only for these tests. You may have to handle cleaning your index after a test/groups of tests as well.

@vich's point is also important, you currently create your object too late, after the request.

I would change your setup to:

context 'GET #index', :search do
  let!(:house) { create(:house) }
  before { get :index }

  it 'assigns @houses' do
    expect(assigns(:houses).results).to eq([house])
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM