Rails testing with static server18 Jul 2022 by Friedrich Ewald · 4 min read
I wanted to test some part of my application that performs HTTP requests against a different website. Now, for testing, I didn’t want to perform actual outside HTTP calls because they tend to become flaky if the internnet becomes unstable or when the remote resource is not available. Another reason, why I didn’t want to use the rails server and their static files, is that I didn’t want to serve those files in production. So I decided to write my own static file server.
The requirements are quite simple. I wanted something that I can spin up from Ruby in the current process and that is able to serve static files from a predefined folder. For this purpose, I created a
files folder under
fixtures. The other requirement is that I did not want it to clash with any other server that might be running on the target system. The reason is that I am planning to run this on my CI pipeline and I have very little control over what runs there. Furthermore, if tests run in parallel I didn’t want to spend much time on synchronization, instead spin up a temporary server for each test and shut it down immediately afterwards.
I came up with two methods that I added to the
test_helper.rb in my Rails application:
replace_port!. The former starts a server and returns the instance of the server itself, giving full control over the server process, including shutdown. This is intended if the server should run for a whole suite instead of for a single test. The block mode allows to start a server inline, and end it immediately. This mode is intended for cases when only a single tests uses the server. See the following example for example usage.
As the port number is dynamic, the HTTP calls also need to be constructed dynamically. I found that it is relatively easy to write
<PORT> in my URLs and then use the small helper method
replace_port! to replace the port via regular expression inline.
The complete code for the methods
replace_port! is listed below. The dynamic port number is achieved by passing
0. This tells the system to use the first available port. The server is started in a different thread to be non-blocking and automatically shuts down upon receiving a
Besides the installation of the
webrick gem, that is all that is needed to serve static files during tests in Rails from the