Adventures in Software Development

Tag Archives: TDD

Unit Tests

This weekend, I finished up adding unit tests and code coverage reports to the Excido solution. I was able to get 100% code coverage on my data model project and my service/business layer project.

I did not attempt to write tests for the other layers for several reason, the most important being that with the exception of the front end, AngularJS project and a utility project, the other layers are almost entirely configuration and specialization of third-party libraries like Web API, Breeze and Entity Framework. That isn’t to say that those layers shouldn’t have unit tests, but I’ve made a decision to use my time working on other parts of the project for now. If I had more resources, the front-end project and the utility project would definitely have unit tests.

Having unit tests on the data model and business layers gives me confidence that the most important parts of the project cannot inadvertently be broken without me knowing it. The tests can run locally on my machine as I’m coding, but more importantly, they are automatically run on the build server whenever any new code is checked in. If any new code breaks something important, I’ll be notified right away. This gives me the ability to make big changes to the software without worrying about breaking old code.

Having the test harness configured and working also allows me to easily start using TDD or Test Driven Development. TDD is a software development process where the developer first writes a unit test that defines what the software should do and then writes the software so that it passes the unit test. This encourages simple designs, inspires confidence and provides for technical documentation of what the software is supposed to do.

Up until this point in the project, I’ve written all of my code first and just got around to writing unit tests after. From here on out, for the important layers, I’ll be writing the unit tests first and then writing the code to make the unit tests pass.

Code Coverage

Code coverage is simply a measure used to describe the degree to which the source code of a program is tested by a particular test suite. A program with high code coverage has been more thoroughly tested and has a lower chance of containing software bugs than a program with low code coverage.

Since the data model and business layers of this project will contain all of the code that will dictate how the software will work, it is important to me that as much of the code is tested as possible. The code coverage report that my testing software gives me shows me that currently 100% of my important layers are covered by unit testing. Knowing this, I can confidently add code to these layers without worrying that some obscure part of the code might be affected. I know because 100% of the code, even the obscure branches that might hardly ever get run, will be tested.

Moq

While writing the unit tests, I made extensive use of Moq. Moq is a mocking framework written specifically for .NET that uses LINQ expression trees and lambda syntax.

Mock objects are simulated objects that mimic the behavior of real objects. Last week, I wrote about using dependency injection and interfaces. Because each of my components delegates it’s work to other components that are only referenced through interfaces, the behavior of any single component can be tested without using any other specific component. Therefore, special components that always behave in specific ways can be injected into a component that is being tested to be sure that the component is always being tested in exactly the same situation. The special components that always behave in specific ways are the mock objects.

For example, last week I described how my repository layer requires an implementation of the IDataContext interface to delegate fetching records from database. In the actual software, there is an implementation of the IDataContext that uses Entity Framework to fetch data from the database. When I’m testing my repository layer, I don’t want to set up Entity Framework and maintain a special database that has to be returned to a certain state every time I want to test. Since the repository layer can work with any IDataContext, I can give it an implementation that doesn’t use Entity Framework but instead always returns a specific set of records of my choosing. That special implementation of IDataContext is a mock object.

Writing special implementations of all of the interfaces required to test a class can be tedious and time consuming. Moq makes this very easy by allowing the declaration and behavior of mock objects to be written in-line using LINQ Expressions.

Take a look at line 9 of the unit test for the GetSlugContent method of the repository:

In that one line of code, I am able to declare an implementation of the IDataContext interface that always returns a specific list of records regardless of what query is run. Under any other circumstances, this would be useless, but when I’m testing that my repository layer is faithfully returning the records given to it by the underlying data context, this is perfect.

Moq can do so much more and writing effective unit tests without it would make unit testing on a one-person project like this one almost impossible.

Progress

Much of the work over the past several weekends has been invisible — adding a repository layer and setting up unit testing. It may be hard for people on the outside of the project to appreciate the importance of this work, but it will definitely make work easier as the project evolves and things need to be changed.

Hopefully, next weekend I can make some visible progress to keep the stakeholders happy. 😉