Tag Archives: Moq

How To Mock Dependencies In Unit Tests

Writing unit tests for your code base is extremely valuable, especially in the DevOps world we’re living in. Being able to automate and execute those unit tests after each round of changes ensures your code base is, at the very least, functional.



But sometimes we need to be able to write a test for a function that connects to some other service. Maybe it connects to a database or it connects to a 3rd party service. Maybe also, this database or service isn’t currently available from your local work stations or hasn’t completed development yet. Better yet, what if we want to run our unit tests as part of our DevOps build pipeline on server that doesn’t have an open connection to our 3rd party service?

Advertisements

In any of these cases, we need to find a way to write our code, and test our code without having to connect to that extra service. In .NET this can be done with Moq. Let’s start off with what Moq is. Moq is an open source code base on GitHub. It provides functionality to write “fake” implementations of things like databases that we can then test against. We can get a better understanding by looking at some examples.

Say we have a function that looks like this:

void AddDatabaseNumbers()
{
   Database db = new DatabaseHelper();
   Connection conn = db.CreateConnection("172.23.42.134");
   string query = "select number1, number2 from numberTable";
   Table results = db.Execute(query);
   return results.number1 + results.number2;
}

When we run this function it is going to connect to our database, execute a query, and then add the two results together. If we were to write a unit test for this it might look like:

[Fact]
public void TestAddNumbers()
{
   AddDatabaseNumbers();
}

In our development environment this test might pass just fine. It connects to the database and executes the query no problem BUT when we push this code to our repository and kick off the next build, the unit test fails. How come?

Well in this case, our build server doesn’t have a direct line of sight to our database, so it can’t connect and therefore the unit test fails trying to make that connection. This is where Moq can help!

Instead of having the function connect to the database, we can write a “fake” connection that pretends to do what the “db.CreateConnection” does. This way the rest of our code can be tested and we don’t have to worry about always having a database available. We can also use Dependency Injection (more on that in a later post)!

Here’s how we can rework this with a Mock. First let’s refactor our function to pass in the Database object so we can Mock its functions:

void AddDatabaseNumbers(Database db)
{
   Connection conn = db.CreateConnection("172.23.42.134");
   string query = "select number1, number2 from numberTable";
   Table results = db.Execute(query);
   return results.number1 + results.number2;
}

Now let’s look at how our unit test will change to mock the database functionality:

[Fact]
public void TestAddNumbers()
{
   var mock = new Mock<Database>();
   mock.Setup(db => db.CreateConnection()).Returns(Connection);

   var fakeQuery = "blah do nothing";
   mock.Setup(db => db.Execute(fakeQuery)).Returns(Table);

   AddDatabaseNumbers(mock.object);
}

What we’ve done here is that instead of passing a true Database object to our function we’re passing in this mock one. The mock one has had both of it’s functions ‘CreateConnection’ and ‘Execute’ setup so that instead of actually doing anything they just return a ‘Connection’ and ‘Table’ object. We’ve essentially faked all of the functionality that relates to the database so that we can run our unit test for all of the other code.

Advertisements

Now when we push our code changes up to our repository, the unit tests run and pass with flying colors, and since we used Dependency Injection to pass our Database object to the function our unit tests can use the mock object and our actual production code can pass the real Database object. Both instances will work as they should and our code is all the better for it!

I highly encourage you to write unit tests for as much code as you can and to take a look at the Quickstart guide for writing Moq’s to get a better understanding: Moq Quickstart Guide.