I'd like to test the HTTP API of our Rails app using Faraday and RSpec. Faraday needs the host url + port. Unfortunately the port of the testing environment does always change. How do I access the current port programmatically in the spec?
相关问题
- Question marks after images and js/css files in ra
- Using :remote => true with hover event
- Eager-loading association count with Arel (Rails 3
- Is there a way to remove IDV Tags from an AIFF fil
- Rails how to handle error and exceptions in model
相关文章
- Right way to deploy Rails + Puma + Postgres app to
- AWS S3 in rails - how to set the s3_signature_vers
- how to call a active record named scope with a str
- How to add a JSON column in MySQL with Rails 5 Mig
- “No explicit conversion of Symbol into String” for
- form_for wrong number of arguments in rails 4
- Rspec controller error expecting <“index”> but
- Rspec controller error expecting <“index”> but
There's probably more than one way to do this, but this is working for me right now:
The command
Note that you'll have to do this at some point after the app has loaded - i.e., you can't use this in your
environment.rb
orapplication.rb
file.The explanation
Basically what this command does is as follows:
lsof
is the Unix command for LiSt Open Files-p #{Process.pid}
limits it to the current process (i.e., your test web server instance)-ai TCP
limits it to "files" of type TCP (i.e., open TCP ports). (Note: the-a
is to make it AND the search with the pid one - the default, using just-i
would OR the search)-as TCP:LISTEN
limits to just TCP ports that are being listened on (as opposed to any open port - like your app's connection to Postgres for example)-Fn
tells it to only output the "name" column, which in this case will be the IP/port that is being listened onThe output of that part by itself will be something like this:
The first line, starting with
p
is the process ID. There's no way to suppress this. The next 2 lines (not sure why it can output multiples, but we'll take care of it in a minute) are the "name" column (hencen
), followed by the IP + port. In our case (and I imagine yours as well, in a test environment), the web server listens on all available local IPs, thus*
. Then it tells us that the port is, in this case 5001.Finally, we pipe it through... *
grep ^n
to eliminate the first line (the process id) *cut
to say "cut from columns 4 on" - i.e., remove then*:
to return just the port, and *uniq
to just get the one instance(It will also have a trailing newline, thus the
strip
call.)The usage
In my case, I'm using this in my Cucumber
env.rb
thusly, to reconfigure the URL options for ActiveMailer so my email links get generated properly as working links in test:port =
lsof -p #{Process.pid} -ai TCP -as TCP:LISTEN -Fn | grep ^n | cut -c 4- | uniq
.stripMyApp::Application.configure do config.action_mailer.default_url_options[:host] = "0.0.0.0:#{port}" end
No doubt you could do the same thing in a helper/config for Rspec as well.
If using Capybara you can set the port in the spec_helper.rb like so:
See also: https://github.com/jnicklas/capybara/pull/123