测试环境下Searchkick手动重新索引关联时出错问题排查
Hey there, let's tackle those two reindex errors you're facing with Searchkick in your test setup. You mentioned you already set Searchkick.disable_callbacks in your test_helper.rb—that's a good start, but we need to adjust how we handle manual reindex calls for each environment.
1. CI Environment: 9200 Port Unavailable (No ES Running)
Since your CI environment doesn't have Elasticsearch running, any direct call to reindex will fail because it can't connect to the ES instance. Here are two straightforward fixes:
Mock the reindex method in tests
If your tests don't actually need to verify ES indexing behavior (since callbacks are disabled), just mock thereindexcall to avoid hitting the nonexistent ES server. For example, in RSpec:# In your test file allow(Parent).to receive(:reindex).and_return(true) # Or for an instance: allow(parent_instance).to receive(:reindex).and_return(true)For Minitest, you can use
mochato stub the method:Parent.stubs(:reindex).returns(true)Conditionally skip reindex in CI
If you have a task that triggers reindex as part of your test setup, add a check to skip it when ES isn't available. You can check if the port is reachable, or use an environment variable:# In your test setup or rake task begin Socket.tcp('localhost', 9200, connect_timeout: 1) Parent.reindex rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH puts "Skipping reindex: Elasticsearch not available" end
2. Local Environment: "Document Doesn't Exist" Error
When callbacks are disabled, creating a Parent record won't automatically index it into ES. So when you call reindex manually, there's no existing document to update. Here's how to fix this:
Temporarily enable callbacks when creating test records
If you need to test reindex behavior, enable callbacks just for the record creation so it gets indexed initially:# In your test parent = nil Searchkick.enable_callbacks do parent = Parent.create!(client: test_client, ...) end # Now reindex will work because the document exists in ES parent.reindexManually index the record before reindexing
Alternatively, you can manually add the record to the index without enabling callbacks:parent = Parent.create!(client: test_client, ...) # Manually index the record first parent.index # Now reindex will find the document parent.reindex
Quick Recap
- For CI: Mock or skip reindex calls since ES isn't running.
- For local tests: Ensure the record is indexed (either via temporary callbacks or manual
indexcall) before runningreindex.
内容的提问来源于stack exchange,提问作者Dan

