So, I was working a rails4 project today and added an
after_create method to a model (call it model A) that checked on a related object (call it model B) to see its state, and if it met a certain criteria, did something to the model A object being created. The specifics don’t really matter, but I was using zeus to run my rpsec tests.
This caused three tests to fail in entirely unrelated sections of the application.
What on earth was going on?
Well, first I used
git bisect to determine the exact commit that caused the issue. (As far as I’m concerned, the existence of
git bisect confirms my belief to ‘commit early, commit often’).
Then I dug in. It appears that each of the tests was tweaking the model B object, and testing some aspect of the change, usually through the model A object. Before I added the
after_create method, the model B object wasn’t loaded into the ActiveRecord in memory network graph tied to the model A object when the test saved the model A object initially, but was loaded from the database when the method under test executed.
after_create method was added, the model B object was loaded into the in memory network graph tied to the model A object. Then the test tweaked the model B object in the database, but didn’t reload the model A object, which had a dirty/old version of the model B object.
A simple reload of model A (and its network graph) fixed it (or a repositioning of when I modified the model B object), but it was quite a subtle testing bug to track down.