Testing abstract Rails controllers

Abstract controllers like the ApplicationController are hard to test in isolation. You can get usually around this by testing a concrete implementation, but that might not be feasible for testing edge cases.

Similarly, Rails engines are a little difficult to test. A new engine comes with a "test dummy" app that you can use to test the various features. It's good enough to test the happy path, but it's hard to test edge cases without adding new controllers.

RSpec makes testing these a little easier though has the concept of anonymous controller specs; it's a feature that lets you define a temporary controller within the tests themselves. I like Minitest and wanted an analogous feature for it, so I did some research.

Once I had a working proof of concept, I published Rails Anonymous Controller Testing, a gem that lets you define and test anonymous controllers in Minitest for Rails. It involves quite a bit of metaprogramming, but it's pretty straightforward, and most of the code lives in one file.

Small note, it is a little different from RSpec since RSpec's is built atop controller tests while this gem is built atop integration tests. If you build a gem for RSpec that utilizes integration tests and has overrideable views, please let me know!

I'm already using it in Super, a Rails engine that provides generic CRUD functionality through an inheritable controller. It's especially useful there since it has nine identical dummy apps; I test a combination of Rails versions from 5.0–6.1, Sprockets versions 3 and 4, and Webpacker versions 4–6. Although I have some automation to keep all nine apps in sync, it's still a bit more manual work and verification than is pleasant.

Here's the gem and the source code. I know that the Minitest community is pretty small, but I hope this helps you too!

Posted on 2021-08-09 03:58 PM +0900
Contact
hello(at)zachahn(dot)com
© Copyright 2008–2021 Zach Ahn