Google Analytics

Friday, July 14, 2017

Introducing Mountebank!

I want to preface this next post with a bit of a disclaimer: The technical posts I primarily make tend to come from the point of view of someone with two thumbs (this guy) who is exploring some piece of technology new to him. I do it primarily for my own benefit. Having to create a blog post forces me to approach the subject in an organized manner rather than just going off and willy-nilly experimenting to no purpose. Secondly, I can document my own process as much for me to go back and diagnose issues I run into (see my last post) as it is to pass along that documentation to others I am working with. Finally, usually whenever I Google some troublesome issue no matter hwo obscure I think it might be, there are a couple developers out there that have run into the same or similar issue, and blog posts of others working through those issues have saved me a lot of time, if not my hairline. I feel like, no matter how small, maybe if I share, some other developer might find some little nugget that will help them get through some similar issue.

So if you're already an expert with mountebank and are looking for some new insight, you aren't going to find it here. Instead, I really hope you read through this series of posts and add your own insights or corrections, for there are sure to be some.

With that let me introduce (*some old-timey fanfare plays on a nickelodeon*) mountebank! Mountebank is an old-timey word for imposter or charlatan, a snake-oil salesman. In this context mountebank (I use MB for short here) is an open-source tool for impersonating related services in software testing. Automated testing of downstream service calls can, frankly, be a bitch. Yes, you can work out some mock, but service calls are way more unpredictable than a simple mock. What if the service or port is unavailable? What is the service returns some garbage response? How about creating integration tests dependent on some vendor service that you don't have a test environment for? These are the sort of things that mountebank can help solve.

MB runs on node.js, so it's simplest to intall it using with node package manager, though there is a separate install. I won't rehash the installation and first steps outlined in "Getting Started" of the MB documentation. To summarize it though, once you get it installed with npm, you can start it with the command 'mb' from the command line and see it working by putting "http://localhost:2525" into a browser. by default the api runs on port 2525. What the browser shows is the same documentation as is at the mountebank site.


Mountebank uses "imposters" to listen on a given port and react to requests with programmed responses. I say "programmed responses" as opposed to canned responses because, as we will see, there is a good deal of lattitude in supplying a response to any given request. 

Each imposter can have one to many stubs. A stub is a mapping of a request to a set of responses. A stub uses predicates to match against the incoming request. The predicate defines a set of information and if the incoming request matches the incoming request, then the next response in the set of responses defined for the stub is returned back to the caller. The set of responses is circular: MB takes the next response in line, returns it, and then puts that response to the back of the line. In this way you can impersonate a service that returns different responses for the same request.

To summarize the basic workings of using mountebank when testing, in your test setup (or test fixture) you start the MB API, then add an imposter and stub, make a request to the imposter service and then evaluate the response it returns.

In our projects we are generally handling applications for credit cards. One of our downstream services is a vendor who makes the decision on whether an application qualifies for a card, what sort of card, and how big of a credit line. We use MB to "fill-in" for the outside vendor service. We can use predicates to match on the (fake) social security number on an application, or the user's income, for example, and return any of a number of responses based on what our vendor would actually send.

In my next post, I'll actually demonstrate a service under test along with the related setup for some MB imposters.

There is a .Net library for utilizing the MB API out there called MbDotNet. I tried it out, but off the bat saw that it wasn't going to be adequate for the testing I wanted to do. You may have more luck. It's definitely a project I would be interested in contributing to, because I'm a true believer in using MB, and would love to make it easier for .Net devs.

No comments: