Thursday, February 9, 2012
Pairing Tour: Day 7
Today I got to pair with Doug Bradbury on some Rails work. Doug is currently working on a new project, so we got the chance to lay some of the foundation of the app. All of the stories for the iteration are currently blocked because they are dependent on work being done by other developers, so we got they rare opportunity to spend the day refactoring. For this Rails app we are trying to use the Boundary, Interactor (Control), Entity pattern inspired by Uncle Bob. The goal of this is to make our tests much faster. By decoupling our business logic from our delivery mechanism, we will produce a better design that is easier to test. So we started by refactoring a controller action to not depend on an Active Record model. The required us to isolate the calls and return values from active record in our interactor (business logic module). Once we finished this we decided that we wanted to remove the dependency on Active Record from our interactor. So we started to abstract the calls to Active Record into Database transaction objects. These objects represent one transaction with the database in the same way that application interactors represent one business rule. So, we created one Transaction class title FindAuthorizationByNameAndUid. The name of transaction itself clearly represents what this module is supposed to do. It can be implemented using Active Record or any other persistence mechanism. Most importantly, it can be easily mocked out in tests my an in-memory equivalent. By the end of the day we were able to remove Active Record models from the interactor and put them into transaction objects. The refactoring of the code was really easy. Since our interactor was already tested, we made all the refactors that we wanted and the tests still passed. However, we were unable to refactor our tests to not use active record objects. This is little bigger of a task because the in-memory test double must be built first. So, I'm going to pair with Doug again in the morning to see if we can find a good way to test the interactor without using the Database. All in all, it was a very enlightening day on how to decouple application logic away from Rails.