Testability of East Oriented Code

Introduction

By Urville DjasimJames Ladd wrote great post about East Oriented Code. In this post we’ll discuss the influence of east code on its testability.

For simplification, east code is mainly characterized by that all public methods return void. Usage of this “rule of void” makes the code focus on the “Tell, don’t ask” attitude.

What does it have to do with testability?

For making things simpler, let’s go over a simple example based on the MoviesLister used in James post. The goal of this code is to add stars to Steven Spielberg movies.

West code

West tests

[TestMethod]

var fakeNonSpielbergMovie = Isolate.Fake.Instance<WestMovie>();

Testing this code is very straight forward. All needed to be done is give basic inputs to the classes and easily check the state of the returned values.

East code

East tests

The moment we start thinking of a test we see that there is no state to verify against:

This method has no return value, so there is nothing to check there. Unit testing this method forces us to test the interaction between the objects.

What are we going to check? We can check that EastMovie.IfDirectedByDo was called. We can also check that EastMovie.AddStar was called, we can check if the IMovieAction.ApplyTo was called and we can check if EastFinder.FindAllAndApply was called. What should we choose? Since we’re unit testing we’ll choose the closest object – EastFinder.

First attempt


After taking a close look at this test – what it does is actually reversing the code logic. Does this test ensure that if we send an AddStarAction Spielberg’s movies will get another star? Not really, it doesn’t even check if the passed action is the AddStarAction. Also, we know we can’t verify it. It will be over specification (and in this case it won’t really work).

Second attempt

What we have now? We’re sure our action was called. We could also verify it was called with our fake movie, but again, it’s over specification. Second attempt and our test is still away from being satisfying.

Third attempt

This test takes us one step further. Now we have more confidence that our test actually tests what it’s intended to. This test is surly not enough. If we want to be sure this test is OK we have to check that our movie adds one star only. This make us count the calls to AddStar, we have no other way since EastMovie doesn’t have a getter that tells us how many stars it has.

What have we learnt so far?

As we can see from our last test, in order to get high confidence even simple unit tests looks like integration test. East code has better encapsulation of its state which makes it harder to test the state and forces us to check the interaction.

Conclusion

East code improves encapsulation but reduces out ability to write tests against objects states. Code with strong east orientation will have more interaction based tests than west oriented code.

If so, should we reduce our east orientation to improve its testability? In my opinion – No. Orienting east makes the code having more classes with focused responsibility. These kind of classes are less likely to change and of course smaller (by code and interface).

How’s the conclusion fits all of the above? East orientation is a compass, it helps us aim to better code:

“The structuring of code to an East orientation decreases coupling and the amount of code needed to be written, whilst increasing code clarity, cohesion and flexibility. It is easier to create a good design and structure by simply orienting it East.”

With these qualities, we have focused tests (yet, interaction based) on focused classes. Focused code is less likely to change, and focused classes are easier to test – this is the major advantage we gain by adjusting to the east oriented code.