RSpec — Controller or Request Specs?

Ministry of Justice Digital & Technology
Just Tech
Published in
3 min readNov 16, 2018

by David Elliott (Software Development Profession)

We recently started a new Rails 5 project, and a conversation started around if we should be using RSpec controller or request specs. A quick google search shows that in the RSpec 3.5 release notes the recommendation is as follows:

“For new Rails apps: we don’t recommend adding the rails-controller-testing gem to your application. The official recommendation of the Rails team and the RSpec core team is to write request specs instead.”

And the readme has been updated to say:

“Controller specs can be used to describe the behaviour of Rails controllers. As of version 3.5, however, controller specs are discouraged in favour of request specs (which also focus largely on controllers, but capture other critical aspects of application behaviour as well). Controller specs will continue to be supported until at least version 4.0 (see the release notes for details).”

So what are the differences between controller and request specs, and when should we use each?

Controller Specs

Controller specs are RSpec wrappers for Rails functional tests. They simulate a single HTTP request in each example. By default views are not rendered; the controller spec stubs views with a template that renders an empty string (the template must exist). As you only call a controller action, only the controller is tested.

Here we are testing that the response is successful, it assigns the user to the users instance variable, and that it will render the correct template (note that it doesn’t actually render the template).

Pros

  • Test controller actions
  • Fast

Cons

  • No longer recommended by Rspec
  • Some methods now deprecated (assignsand assert_template)
  • Doesn’t test entire stack

Request Specs

Request specs are RSpec wrappers for Rails integration tests. They are designed to test the entire stack, including routing. You can specify single or multiple requests across multiple controllers or sessions. If we look at an equivalent test we created in the controller example above:

Here we test the users controller action as before. In addition, we also test that our routes file correctly routes the users_path route to the controller action, as well as rendering and checking the content on our page. If we were redirecting to another page, or wanted to do multiple requests, such as a GET and a POST in the same example, we could do that as well.

Request specs give you the ability to test what your application does, rather than how it does it. For example, instead of testing that the right template is rendered in a controller spec, with a request spec we can test that the content we are expecting to appear actually appears in the response body.

Pros

  • Test entire stack
  • Fast
  • Recommended by Rspec

Cons

  • For existing applications using controller specs, effort required to upgrade

Conclusion

Request specs allow you to test the entire application stack, and although there were some concerns raised about speed (in Rails 4 request specs were slower than controller specs), since Rails 5 request specs are now faster than both were in Rails 4.

So which should you use? For new applications, the recommendation is clear — Request specs should be used. For existing applications support for controller specs will remain until at least RSpec version 4.0, but it is something to be aware of and whenever tests are added or updated switching to request specs would be a good idea. There is really no reason to use controller specs over request specs going forward.

References:

http://rspec.info/blog/2016/07/rspec-3-5-has-been-released/

https://github.com/rspec/rspec-rails

https://relishapp.com/rspec/rspec-rails/v/3-8/docs/controller-specs

https://relishapp.com/rspec/rspec-rails/v/3-8/docs/request-specs/request-spec

~~~~~~~~~~~~~~~~~~~~

If you enjoyed this article, please feel free to hit the👏 clap button and leave a response below. You also can follow us on Twitter, read our other blog or check us out on LinkedIn.

If you’d like to come and work with us, please check current vacancies on our job board!

~~~~~~~~~~~~~~~~~~~~

--

--

Ministry of Justice Digital & Technology
Just Tech

We design, build and support user-centred digital and technology services for the justice system.