Freddy Rangel
Freddy Rangel

Reputation: 1363

How to Test Elasticsearch and Searchkick with RSpec

Thanks for taking a look at my question guys. I've been failing miserably at making my test pass and so I'm turning to the fine people at StackOverflow. Any help would be stellar! I've followed this answer to help set up my tests:

Testing searchkick with RSpec

Here's my failing test

provider_controller_spec.rb

describe "#set_locations" do

  let(:provider) { create(:provider) }

  before(:each) { login(provider) }

  context "with search params" do

    let(:location) { create(:location) }
    let(:business) { create(:business, locations: [location]) }

    before(:each) do
      Business.searchkick_index.refresh
      get :set_locations, locale: "es", id: provider.url , query: business.commercial_name
    end

    it "should return search results" do
      expect(assigns(:businesses)).to eq([business])
    end
  end
end

I get the following error:

Failures:

  1) ProvidersController#set_locations with search params should return search results
     Failure/Error: expect(assigns(:businesses)).to eq([business])

Diff:
   @@ -1,2 +1,55 @@
   -[#<Business id: 99, email: nil, commercial_name: "Cazares Ledesma Hermanos", ruc: nil, phone: nil, razon_social: nil, website: nil, account_type: nil, created_at: "2014-04-02 16:42:26", updated_at: "2014-04-02 16:42:26", subcategory_id: nil, password_digest: nil, token: "0tw3uj7oy7q", slogan: nil, description: nil>]

   +#<Searchkick::Results:0x007f99420d7a18
   + @facets=nil,
   + @max_score=0.0,
   + @options=
   +  {:load=>true,
   +   :payload=>
   +    {:query=>
   +      {:dis_max=>
   +        {:queries=>
   +          [{:multi_match=>
   +             {:fields=>["_all"],
   +              :query=>"Cazares Ledesma Hermanos",
   +              :use_dis_max=>false,
   +              :operator=>"and",
   +              :boost=>10,
   +              :analyzer=>"searchkick_search"}},
   +           {:multi_match=>
   +             {:fields=>["_all"],
   +              :query=>"Cazares Ledesma Hermanos",
   +              :use_dis_max=>false,
   +              :operator=>"and",
   +              :boost=>10,
   +              :analyzer=>"searchkick_search2"}},
   +           {:multi_match=>
   +             {:fields=>["_all"],
   +              :query=>"Cazares Ledesma Hermanos",
   +              :use_dis_max=>false,
   +              :operator=>"and",
   +              :fuzziness=>1,
   +              :max_expansions=>3,
   +              :analyzer=>"searchkick_search"}},
   +           {:multi_match=>
   +             {:fields=>["_all"],
   +              :query=>"Cazares Ledesma Hermanos",
   +              :use_dis_max=>false,
   +              :operator=>"and",
   +              :fuzziness=>1,
   +              :max_expansions=>3,
   +              :analyzer=>"searchkick_search2"}}]}},
   +     :size=>100000,
   +     :from=>0,
   +     :fields=>[]},
   +   :size=>100000,
   +   :from=>0,
   +   :term=>"Cazares Ledesma Hermanos"},
   + @response=
   +  {"took"=>2,
   +   "timed_out"=>false,
   +   "_shards"=>{"total"=>1, "successful"=>1, "failed"=>0},
   +   "hits"=>{"total"=>0, "max_score"=>nil, "hits"=>[]}},
   + @results=[],
   + @time=2,
   + @total=0,
   + @wrapper=Tire::Results::Item>

Here's what I'm testing:

providers_controller.rb

def set_locations
  @businesses = Business.search(params[:query], page: params[:page]) if params[:query].present?
end

business.rb

class Business < ActiveRecord::Base
  include Tokenable
  searchkick language: "Spanish"
  searchkick autocomplete: ['commercial_name']
  searchkick word_start: [:name]
  searchkick settings: {number_of_shards: 1}

  validates_presence_of :commercial_name

  has_many :locations, :dependent => :destroy

  accepts_nested_attributes_for :locations,
    reject_if: lambda { |a| a[:street_address].blank? },
    :allow_destroy => true
end

I added this to spec_helper.rb

config.before :each do
  Business.reindex
end

Upvotes: 2

Views: 2676

Answers (1)

Andrew Kane
Andrew Kane

Reputation: 3236

Try:

expect(assigns(:businesses).results).to eq([business])

Also, in your Business model, combine your searchkick calls:

searchkick language: "Spanish",
           autocomplete: ['commercial_name'],
           word_start: [:name],
           settings: {number_of_shards: 1}

(Separate calls will produce undesirable results and this will throw an error in the next release of Searchkick)

Upvotes: 2

Related Questions