Ask A Question

Notifications

You’re not receiving notifications from this thread.

Setup Searchkick with Minitest

Patrício asked in Testing

Hi everyone,

Just followed the searchkick official's docs to setup the tests, so that I can test my search controller:

Let's assume I have the following model:

class User < ApplicationRecord
searchkick

    def search_data
      {
        first_name: first_name,
        last_name: last_name,
        email: email,
        emergency_contacts: build_emergency_contacts_data
      }
    end

    def build_emergency_contacts_data
      emergency_contacts.map do |contact|
        {
          id: contact.id,
          name: contact.name,
          email: contact.email,
        }
      end
    end

  has_many :emergency_contacts, dependent: :destroy
end

The following controller:

class UsersController < ApplicationController
  def search
    response = User.search(params[:query])

    render json: response, status: :ok
  end
end

With that, I wrote the following test:

require 'test_helper'

class UsersSearchTest < ActionDispatch::IntegrationTest
  def setup
    Searchkick.enable_callbacks
  end

  def teardown
    Searchkick.disable_callbacks
  end

  test 'search users' do
    create(:user, :reindex)
    create(:user, :reindex, first_name: 'Jane', email: 'jane.doe@example.com')
    create(:user, :reindex, last_name: 'Smith', email: 'john.smith@example.com')

    get '/users/search', params: { query: 'john' }

    assert_response :success
    assert_equal 2, response.parsed_body["query"].size
  end
end

this is my users factory:

FactoryBot.define do
  factory :user do
    first_name { "John" }
    last_name { "Doe" }
    email { "john@example.com" }

    trait :reindex do
      after(:create) do |user, _evaluator|
        user.reindex(refresh: true)
      end
    end

    trait :with_emergency_contacts do
      after(:create) do |user, _evaluator|
        create_list(:emergency_contact, 2, user: user)
      end
    end
  end
end

Running the previous test, I expect it to pass. But instead, I am getting the following error:

Error:
UsersSearchTest#test_search_users:
Searchkick::InvalidQueryError: Bad mapping - run User.reindex
    app/controllers/users_controller.rb:7:in `search'
    test/integration/users_search_test.rb:29:in `block in <class:UsersSearchTest>'

Why to I need to rerun User.reindex, when my factory already does it?

With that Error, I did the following change:

test 'search users' do
    create(:user, :reindex)
    create(:user, :reindex, first_name: 'Jane', email: 'jane.doe@example.com')
    create(:user, :reindex, last_name: 'Smith', email: 'john.smith@example.com')

    User.reindex

    get '/users/search', params: { query: 'john' }

    assert_response :success
    assert_equal 2, response.parsed_body["query"].size
  end

Now the tests passes, but calling User.reindex after create(:user, :reindex) feels redundant. Also, the test becomes very slow:

Running 1 tests in a single process (parallelization threshold is 50)
Run options: --seed 43504

Running:

.

Finished in 4.227345s, 0.2366 runs/s, 0.4731 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips

What am I missing?

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 83,038+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.