As much as I like BDD (Behavior Driven Development) approach to test automation one problematic question that always comes up is “How do I mock responses from API dependencies”. More often than not your application relies on one or more APIs in order to function. In order to keep the tests stable and self-contained any data outside of the application being tested needs to remain static.
In a unit test scenario this is a lot more straightforward, using approaches such as dependency injection directly or through one of the countless mocking frameworks you can achieve precisely this objective. BDD based automation is more of a black box testing approach, you are running a functional test on your system and can’t easily inject anything into it.
When we first encountered this problem we went for the simplest and hackiest approach. All the communication in our web app flows through a single HTTP Manager endpoint. We added configuration flag to this endpoint so that when its under test it would scan a mock files directory and if it finds a matching file (to the url being called) it would return the file content, otherwise it would make the real call. This worked quite well and was easy to set up, however from the ideal testing standpoint this is wrong. We are not testing the pure system anymore, we are testing the system plus a hack to make mocking work.
We kept this approach for a while, knowing its failures, up until it did not work anymore. Welcome mobile apps. While technically the same hack is possible, it feels even more wrong to create a build of a mobile app that would come with mock file payloads, push that on the device and then run tests against it.
Our solution was to build a very simple mocking proxy server, which is open sourced here https://github.com/rfdy/mock-server-for-bdd. The idea is not all that different from the first approach, however it does away with making code changes in the app itself:
The mocking proxy comes with a configuration file, that can have any number of API endpoints. When started the server will scan a directory of mock payloads, and when it receives a request it will try to serve from that directory. If nothing matches it will forward the request to the real endpoint, keeping all the original headers. The received request will be forwarded to the app and also saved locally, to help with building future mocks.
That’s pretty much it, simple but very powerful. The only change that one needs to make to their app is to point the API urls to the mock server rather than to the real thing, otherwise the app functions as is. The github repo https://github.com/rfdy/mock-server-for-bdd includes the server as well as an example of using it as a part of a BDD scenario under Behat framework.