TechnologyJan 11, 2019

Unit Testing in .Net Part 1: Unit Test Overview

James Darling

If you asked 10 software developers if automated unit testing is important, you would likely get 10 responses stating, “Yes, it is!” Unfortunately, if you also asked these same 10 developers what automated unit testing is and how to implement it, you would also likely get 11 different definitions and best practices.

In this series of articles, my goal is to take a step back and try to bring some clarity to the discussion. While the examples you see will use C# and .NET, I hope the posts will help you build tests in any object-oriented language. Our examples will also follow the sales department at the fictional company Lumber Jacks ‘R Us to see how unit testing improved their software.

In this first article, we are going to start from the beginning by trying to understand what unit testing is and why it is so important.

what is a unit test?

Simply put:

A unit test is a tool to validate that a single unit of code performs a desired functionality.

For our purposes, we can define a “single unit of code” as a grouping of code that performs a single function. In our example, these will be single-function methods.

why are unit tests important?

Unit tests can benefit development teams, regardless of the team’s composition. Some teams have an influx of new developers with little knowledge of the code base. These new team members will often make mistakes when editing code because they do not yet understand the dependencies different classes have with one another. Unit tests can also benefit static teams of experienced developers when there’s a need to make changes to large, complicated systems. A carefully calculated change in one part of the code may still cause a serious error in another part simply because the system is too complex for a single person to memorize all the layers of dependencies.

Often these problems are presented as null reference exceptions in production, which are tricky because they don’t appear until you run the affected block of code. A simple change request to make a property nullable or an edit in how a property is populated may not start throwing errors until your users begin to use the code in a certain situation.

This is where unit tests come in. The goal of unit tests is to give developers confidence that their code works in identified scenarios. In other words, a good suite of unit tests gives developers the ability to press a button and know that new additions to the code base have not changed expected behaviors.

how unit tests help lumber jacks ‘r us

Let’s see an example of a common scenario where a developer would benefit from unit testing.

Paula is the lead architect at Lumber Jack’s ‘R Us (the world’s premier supplier for all your alpine needs). She manages the payroll software and has hired a new developer, Bob, from Mountain Man State University.

Bob’s first task is to make updates to the logic that calculates commissions on sales. Currently, the logic reads like this:

public class PayrollCalculator { public PayrollCalculator() { };   public decimal CalculateComission(double saleTotal) { decimal commission = 0;   if(saleTotal > 1000000) { commission = saleTotal * 0.08; } else { commission = saleTotal * 0.05; }   return commission; }   }

The business has asked IT to add a $500 bonus for salespeople who wear enough flannel during the sales cycle (it’s important for the brand, after all). The business also mentioned that there may be other actions in the future that they will pay bonuses for, so Bob adds a custom object named Actions as property onto the Salesperson. On the Action object, Bob adds a Boolean named WoreEnoughFlannel.

public class PayrollCalculator { public PayrollCalculator() { };   public decimal CalculateComission(double saleTotal, Salesperson salesPerson) { decimal commission = 0;   if(saleTotal > 1000000) { commission = saleTotal * 0.08; } else { commission = saleTotal * 0.05; }   if(salesperson.Actions.WoreEnoughFlannel) { commission += 500; }   return commission; }   }

Bob’s code passes QA testing and Paula approves the code to move to production. However, there’s a miscommunication with the sales managers. To save time, the managers don’t bother to enter data for employees who didn’t wear enough flannel, meaning that some salespeople will have Actions objects equal to null. When it’s time to calculate payroll, the method begins to throw null reference exceptions, grinding the process to a halt and delaying payment to the salespeople. Ouch!

Unit tests could have alerted Bob and Paula to this issue earlier in the development process. A single unit test that simulated a scenario where either of the parameters were null would have brought the issue to the developers’ attention before deploying to production. With Visual Studio’s Live Unit Testing functionality, Bob could have even caught this issue seconds after writing the code!

looking forward

The moral of this part of our story is that automated unit testing better protects your code base from developers introducing new bugs. This is especially valuable for those tricky runtime errors. This scenario is repeated daily across development teams all over the world; it may have even happened recently in your organization!

Hopefully you see the value in adding these types of tests. In the next post, we will cover how to set up automated unit tests in a .Net project.