Mocking downstream services with Mountebank

1. Introduction

I’m a part of a team which creates large enterprise platform for the banking sector. Due to the fact that we operate in the financial area, our application consumes a high amount of downstream services. One of the major problems we are facing at the moment is the inaccessibility of those services on DEV and UAT environments. It often happens that one of those services is down for quite some time, so our development speed is impaired. The bigger problem, however, is the fact that our end-to-end tests are red. Having a red test on TeamCity for a long time is a really annoying thing because basically at this point, we just automatically assume that all of the failures are caused by issues with downstream systems. Fortunately, we finally decided to get rid of this problem and this is the solution we came up with.

2. Background

Before I go to the implementation details, take a look at a sample implementation of situation I described at the very beginning. Let’s assume that we have WCF service which contains business logic of our application and it is consumed by the UI side

BookingFacade uses Pricer service which basically is just a wrapper for external/downstream service we have to use in order to retrieve some data (and we do not have an ownership of that service).

Very simple end-to-end test for BookingFacade can look like that

As I mentioned before, everything is fine as long as all of the downstream systems are working. The moment one of them is down, our tests start failing.
FailingTests

3. Implementation

General idea to fix this problem is to use fake downstream systems during end-to-end testing. In order to do that we use combination of custom compilation profile, app.config transformations and mountebank test doubles.

3.1 Setting up transformations

First of all we will create a custom compilation profile called test.integration which will be used for running tests with mocked downstream systems (we want to preserve the normal use of downstreams for Debug and Release mode). In order to do that, go to ConfigurationManager
ConfigurationManager
and follow the steps presented in the pictures below
ConfigurationManager2
ConfigurationManager3

Now it is time to prepare our app.config for transformations. We can do it manually but for sake of simplicity I will use SlowCheetah extension. Go to Tools->Extensions and Updates and install
SlowCheetah – XML Transforms. Once extension is installed you will see a Add Transform item in a config files’ context menu.
AddTransform
Clicking Add Transform will create three files: App.Debug.config, App.Release.config and App.Test.Integration.config. What is more, some additional changes will be added to your csproj file, which will be responsible for applying transformations during a build process. These three additional files hold information about config transformations. The default App.config file looks like that

Nothing special in here but note the empty file attribute in appSettings node. The value of this attribute will be replaced with proper filename during transformation process. In order to do that let’s implement tramsforms for every of three config files we use

App.Debug.config

App.Release.config

App.Test.Integration.config

As you can see I apply SetAttributes transform for appSettings node, which means that the transformation will replace appSettings node attributes from app.config file with appSettings node attributes from transform file. You can preview results of transformation by clicking Preview Transform context menu option available for every of our transform files
Preview
As you’ve probably already figured it out app.settings.debug and app.settings.release fileses contain real downstream endpoints and app.settings.tests.integration contains addresses of fake endpoints. Of course you have to create those files and copy them to output directory during the build (for instance by using Copy to Output directory option).

3.2. Creating fake downstreams with mountebank

Setting up fake downstream systems completely from scratch would be a very painful and time consuming process. Fortunately there are tools which can make this task easier. The tool I use is called mountebank – you can easily install it via npm

Having mountebank on board it is time to configure it, so that it acts as fake Pricer service. It can be done in couple of ways but I will go with file based configuration. You can run the tool using following command

ImpostorsListening
Where impostors.ejs is a configuration file with following structure

<% include pricer.json %> is EJS syntax which (in this case) allows you to split configuration into multiple files. As you’ve probably already figured it out, Pricer.json contains the actual mock configuration for Pricer service. The initial mock object consists of couple of properties which setup the name, port and protocol for given mock.

Note that we do not specify the address of mock but just a port. Mountebank by default runs on http://localhost:2525 and mocks listen on http://localhost:{port}. The actual magic happens in stubs property.
Here is an example of stub/mock for GetTradingDates method.

As you can see stub object consists of two properties

  • responses
  • predicates

responses property is an array of objects mountebank will be using to create a response. If you insert multiple items into array, they will be utilized using round robin algorithm. Note that you don’t have to create a full response (with all the headers etc.) just use “is” property which will fill the default values for you. More about that topic can be found here but in most of the cases setting value for “body” property will be enough for you.

predicates property is an array of predicates which will be used during matching process. Predicate object can be quite complex, it supports lots of different matching techniques. In this case, for simple GET method I just use equals operator to match HTTP verb and HTTP method.
The same technique can be used for stubbing POST methods. However, in this case, you can also perform matching against the body of the request. The one thing you have to remember is that body property is not an object but string. So in my case, if I want to make a stub for GetPrice which takes as params following request object

I can write for instance this stub

Of course for more complex request it is pointless to write every possible combination of params. Fortunately you can create fallback/default stub which will match everything

If you put this at the very end of stubs array it will not interfere with other stubs.
This is of course just a tip of the iceberg when it comes to predicate matching. Explanation of all possible matching options can be found here

4. Results

From now on running tests against test.integration compilation profile and having mountebank working in the background, our tests will be green.
SuccessfulTests
Source code for this post can be found here

Mocking downstream services with Mountebank

Using async/await with IAsyncResult pattern

Even though in my current project we use .NET 4.5 we still have lots of references to internal libraries targeting .NET 4.0. Usually it is not a problem, however some of these libraries follow Asynchronous Programming Model pattern. This approach makes the code quite ugly because we end up with lots of nested callbacks.

Fortunately thanks to

method it is possible to quite easily make Begin/End methods work with async/await pattern. All you have to do is to pass Begin/End methods as an arguments to Task.Factory.FromAsync and you are good to go. The original code after refactoring looks like that

I think everyone will agree with me that refactored version is much better than original one.
Source code for this post can be found here

Using async/await with IAsyncResult pattern

EntityFramework – SQLException during database migration

Recently I’ve been doing some small refactoring of my pet project. Nothing too fancy – just namespace adjustment, variables and class renaming etc. However it turned out that even these minor changes can in fact be major ones. All of the sudden most of my integration tests started failing due to SQLException.
Exception
I am using Code First approach so I didn’t take me too much time to realize that for some reasons EntityFramework wanted to create already existing tables. I started looking into the way EF keeps track of the changes in the model and it turned out that it creates special table called

ContextKey
One of the most important columns in there is column called ContextKey, which identifies the class which describes migration policy. In my case this class originally looked that way

In that case value of the ContextKey column matches the full name of the class

The class after refactoring was slightly changed and now it looks that way

It is easy to overlook the change but now, full name of the class is

so EF loses the information about the migration and tries to migrate once again from the scratch. Fortunately there is an easy fix for that which doesn’t require dropping the database. All you have to do is to write simple update statement which set the proper ContextKey value.

Source code for this post can be found here

EntityFramework – SQLException during database migration

Abusing collection initializers

Most of .NET developers are familiar with collection initializers syntax. Long story short, this language feature allows you to replace this ugly syntax

with much shorter and cleaner one

The more interesting thing is the fact that you can leverage this syntax not only for build-in collections but also for your custom classes. In order to do that your class must implement IEnumerable interface and expose public Add method. Let’s assume that we have some real case scenario and we have class which looks like that

This is a simple wrapper over the List. At this moment we can’t use collection initializer when constructing objects of this classs. However by adding method Add

we can create a new instance of that class just like we would do with List

What is more, it is possible to have multiple overloads of Add method in our class, so for instance if we add

we are able to use this syntax

In addition it is even possible to use a mix of Add overloads

Add method can also have multiple arguments

in that case we are able to use this syntax

The last thing I would like to point out is that Add function doesn’t have to be an instance method, we can easily implement it as an extension method and still leverage the collection initializer syntax.

Now with proper namespace import we can write this code

Source code for this post can be found here

Abusing collection initializers