9

I use the sunspot-rails for search. These is a Rspec looks like:

describe "GET search" do
  before(:all) do
    system("rake", "sunspot:solr:start")
  end

  after(:all) do
    system("rake", "sunspot:solr:stop")
  end

  it "should do some search" do
    Text.search do
      ...
    end
  end
end

But it doesn't work. I got a failure:

Errno::ECONNREFUSED:
   Connection refused - connect(2)

But if I type rake sunspot:solr:start RAILS_ENV=test by hand in command line, and then run the spec, it passes.

What's wrong? Isn't rake sunspot:solr:start RAILS_ENV=test equivalent to system("rake", "sunspot:solr:start") in test mode?

(I tried `system("rake", "sunspot:solr:start RAILS_EVN=test"). Same.)

Lai Yu-Hsuan
  • 27,509
  • 28
  • 97
  • 164

4 Answers4

14

Your before(:all) probably just isn't giving Solr enough time to start.

That said, you'll probably want to think hard about just what you're asking your specs to verify here. You can go a long way with mocking out calls to Solr with a library like Fakeweb.

Pivotal Labs also has a library called sunspot_matchers that can capture more fine-grained assertions about the searches you're invoking.

If you are going for real integration specs against Solr, I advise just keeping a test Solr running while you work. A tool like Foreman can help manage your Solr proceses. I might use a Procfile like the following:

solr_dev:  rake sunspot:solr:run RAILS_ENV=development
solr_test: rake sunspot:solr:run RAILS_ENV=test

(Development is, of course, the default environment if no RAILS_ENV is otherwise provided to foreman start)

Finally, if you want to start Solr within your specs, you're already on the right track. Just toss a sleep in there with enough time to let Solr fully boot itself before your specs start running. Don't be surprised if that introduces a bit of unpredictable failure into your spec suite when the system is under load.

[Edit: Quick and dirty before :all which uses Sunspot.remove_all to poll for availability.]

before :all do
  `sunspot-solr start`
  begin
    Sunspot.remove_all!
  rescue Errno::ECONNREFUSED
    sleep 1 && retry
  end
end
Nick Zadrozny
  • 7,906
  • 33
  • 38
  • thanks. BTW, how can I know whether solr is running in my spec? I want a more proper custom exception instead of 'connection rejected' – Lai Yu-Hsuan Sep 07 '11 at 08:48
  • I should think that `Errno::ECONNREFUSED` is pretty indicative. In fact, you could use that to poll for availability. Just hacked that out in an edit. – Nick Zadrozny Sep 08 '11 at 00:44
11

The sunspot_test gem will do this for you and supports RSpec.

Simmo
  • 1,717
  • 19
  • 37
0

This is a wild-ass guess, but I bet you have a Solr server configured in your config/environments/development.rb file to look locally on a given port, but no such configuration in your config/environments/test.rb

This is causing it to connect to the default address/port where you do not in fact have a Solr server running when you execute your tests.

I don't know enough about the Solr client in Ruby to be sure of this, but since no one else has weighed in yet I hope this points you in the right direction.

Winfield
  • 18,985
  • 3
  • 52
  • 65
0

I got this working just by adding

`rake sunspot:solr:start RAILS_ENV=test`

to spec_helper.rb

Edit: I ended up going with https://github.com/collectiveidea/sunspot_test like Simmo mentioned. It was re-running the rake task on every test run for some reason (even though I had it in the prefork block of spork). Not sure why, but the sunspot_test gem seems like the way to go for now.

Brian Armstrong
  • 19,707
  • 17
  • 115
  • 144