1

In my rails application I have some backend jobs using Stalker and Beanstalkd. Part of those jobs is to make an API call to the web interface of the application. I want to write an end-to-end rspec test for this job, where the job under test makes an actual API call to the rails application.

Trouble is - I always get connection refused connecting to the default rails web port, 3000:

Errno::ECONNREFUSED: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/webmock-1.24.2/lib/webmock/http_lib_adapters/net_http.rb:136:in `start_with_connect_without_finish'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/webmock-1.24.2/lib/webmock/http_lib_adapters/net_http.rb:104:in `request'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/rest-client-1.6.9/lib/restclient/net_http_ext.rb:51:in `request'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/rest-client-1.6.9/lib/restclient/request.rb:210:in `block in transmit'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/webmock-1.24.2/lib/webmock/http_lib_adapters/net_http.rb:123:in `start_without_connect'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/webmock-1.24.2/lib/webmock/http_lib_adapters/net_http.rb:150:in `start'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/rest-client-1.6.9/lib/restclient/request.rb:206:in `transmit'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/rest-client-1.6.9/lib/restclient/request.rb:68:in `execute'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/rest-client-1.6.9/lib/restclient/request.rb:35:in `execute'
/Users/dalvizu/.rvm/gems/ruby-2.3.3/gems/rest-client-1.6.9/lib/restclient/resource.rb:76:in `put'

I am using rspec to run my tests - so far I tried declaring my test to be of type :feature or :request -- do these start an actual application server and hit port 3000? Is there any way I can do this in my test? Am I using the wrong port?

Greg
  • 5,862
  • 1
  • 25
  • 52
Dan Alvizu
  • 1,291
  • 9
  • 23

1 Answers1

2

You didn't share many details, so I'll try with a high level answer. maybe it's helpful.

:request spec type will not start up the server for you (it designed to test the full stack, including routing, but not including actual HTTP request)

:feature require's capybara, and you make the requests, for example, using visit method. Capybara will start a server and will do HTTP request through a headless chrome or another client. But your Job probably doesn't know that it should use the other server

If you used capybara, you can get the current port, it's explained in this question Cucumber / Capybara -- how to get the host and port of the current execution (don't forget to upvote this one if helpful) And find a way to pass this information to the job you're trying to test.

In general end-to-end tests are hard, when you have an async component to it. How long should you wait for the result of the background job to manifest, and when to declare it failed?

Also, it's weird that your job has to hit HTTP server... it should have easier access to the app objects itself, no?

Unless it's a different app server. Then, you just need to make sure it's running (as a dependency) just like you make sure the DB server is running before you run the specs.

Greg
  • 5,862
  • 1
  • 25
  • 52
  • Thanks - that is helpful. It sounds like I'm off the rails (heh) here in what I want to test. If you are curious on why i'm doing this - well, the job itself is from a legacy app which does not load rails context, in order to save memory back when that was important in 2011. It calls back to the rails app an API to use model logic. The job itself just calls another API. – Dan Alvizu Jun 28 '18 at 16:46
  • 1
    Yeah, I think my answer still makes sense in this context. I'd cover each API as a separate app, have some integration to hold those together and plan to re-factor (on the architecture level) if possible. – Greg Jun 29 '18 at 08:23