Test Driven Development — Fake it to make it

A light introduction, and demonstration of mocks from the perspective of a student

Jack Gifford
3CS Blog
5 min readJan 23, 2017

--

Mocks are a crucial aspect of unit testing; allowing developers to focus on one aspect of code within the solution at a time. Mocking objects isolates each component of code without worrying about dependency on other components. This isolation allows for the testing of individual methods, even if the dependent classes are yet to be implemented. We use mocks to simulate the behaviour of complex, real objects which is useful in circumstances where instantiating a real instance of the object is impractical or outside of the scope of our test. Mocks inherit the same interface as the object they simulate, because of this they have the same signatures, so from a black box perspective there’s no way of differentiating between a mocked object, and the real thing.

Wikipedia states that mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behavior of a human in vehicle impacts.

Common pitfalls that are avoided with mocks

When writing code we often depend on calls to third party services, database polls, and system calls. All of which result in long wait times, incur costs, and reduce your productivity. Instead of relying on these calls during the testing phase of development we can instead mock these objects resulting in faster tests.

1. Calls to third party services

Imagine we’re writing an application that uses SendGrid to send an email to our users after they’ve signed up, the email asks them to verify by clicking the provided link before we can let them use our application. We’ve just written some code that generates an authentication link, composes the email, and sends it to the users supplied email address. We’d like to test out this service but we don’t want to call SendGrid each time, as we’ll start incurring extra cost. We can instead use mocks.

2. Database Polling

We’ve now written some code that handles the process of logging an existing user into our application. The code involves retrieving the hashed password for the user from our database, and then comparing it to the hash the user has just supplied. If it’s correct they’re authenticated. When we go to test this instead of calling a function to poll the database we instead mock that function and return the hashed password without any delay allowing us to focus on code instead of interaction with a database.

3. System calls

On a different note we’re writing a script that will send diagnostics to the printer when certain conditions are met. Having to check the printer each time you run tests is going to get pretty tedious, so we instead mock this.

Demonstration using C# & Moq

In this post we’ll be using Moq, it’s simple to use, and is employed in both simple, and enterprise solutions. Follow along, or download the completed solution here. We’ll model this demonstration off of the database polling problem presented earlier

Getting Started

Create a Console Application inside Visual Studio, and then add a Unit Test Project to the solution.

Install Moq

To install Moq, you can follow the instructions from their GitHub, or just use Nuget:

Database Retriever

We need an interface that handles the interaction with the database. Since we’ll be focusing on unit tests regarding the authentication process we don’t care much about this:

The DatabaseRetriever class isn’t used by our tests but its been included to help understand the problem mocking solves.

Login

We now have a class that will handle authentication with a single function Authenticate which takes the username, as well as the supplied hash and returns true or false depending on whether the supplied hash is the same as the one we have stored in our database.

Our class has one dependency IDatabaseRetriever and it’s this that we wish to mock.

LoginTests

Since our Authenticate method can either return true or false, we’ll write two test methods: Authenticate_True and Authenticate_False

We’ll be following the AAA pattern for all of our unit tests.

Authenticate_True

What we’ve done is used Moq to create a mock instance of IDatabaseRetriever . In the second line we told Moq that anytime RetrievePassword is called with the parameter user1 it should return password. We’re now able to test out the functionality of Authenticate without worrying about querying to a database.

In the first line we’ve instantiated an instance of Login and passed our mocked version of IDatabaseRetriever into the constructor.

We finish off the test by checking that Authenticate returned true.

Authenticate_False

The Arrange portion remains the same but we instead pass notmypassword into authenticate to make sure the function returns false when suppliedHash is different to storedHash.

Takeaway

After a simple but rather contrived example, I hope you’re able to see the benefits of working with mocks, as it allows you to simplify your testing which in turn simplifies your workflow, and increases productivity.

Mock Frameworks for different languages

  • C#: Moq or NUnit
  • Python: mock distriubted as part of the standard library since 3.3. Older versions can download the library from PyPI
  • JavaScript: QUnit maintained and developed by JQuery
  • Java: JUnit

--

--