Who Controls the Controllers?

Learn about controllers, controller testing, duplication controller test, business logic and controllers test, and who controls the controllers.

All of the new tests pass, so let’s take stock of what we have so far. We still have one test pending: our end-to-end test still doesn’t like that the create action can’t be found in the ProjectsController. Now we have all the pieces we need to write that action.

Controller testing as low value

The next question is, are we going to write any tests specifically to target the controller’s logic? The answer, perhaps surprisingly, is no. Or at least not with the tools already discussed.

Controller tests, which have been a feature of Rails initially, have increasingly been seen as lower-value tests in a couple of different ways.

If we write Rails applications the way that the Rails core team writes Basecamp (their flagship application) and follow the process and structures as espoused by Rails founder David Heinemeier Hansson, then regardless of how our controllers are structured, controller tests feel like duplicates of integration tests. Since there has been a lot of work in Rails 5 and higher to make integration tests faster, controller tests become less valuable.

Duplication controller tests

If we do more aggressive test-driven development, or we like moving application logic to separate workflow objects, then the controller doesn’t have much functionality of its own. Then we’re concerned with a controller test duplicating model or workflow tests.

In either case, it’s tricky to write a controller test that covers the controller logic without duplicating other tests. When we learn about test doubles in the chapter “Using Test Doubles as Mocks and Stubs,” we’ll learn a strategy that might help. Rails and RSpec still provide some features for testing controllers, which we’ll learn in the chapter “Testing Rails Display Elements."

Business logic and controllers

Since we’ve put the business logic in the workflow object, the controller doesn’t have much logic, but it does have some. Specifically, the controller sends data both to the workflow object and onward to the view layer. In the current test structure, these functions are controlled by the system test. Notice that responsibilities are separated here. Almost nothing that the controller does is dependent on the logic of creating and saving projects.

Unit testing and error conditions

The controller also needs to do something in case the action object errors or does something else unexpected. Let’s try to create the error conditions at the unit level.

The code to clear the controller-specific lines in the integration test looks like this:

Get hands-on with 1400+ tech skills courses.