Shall I write a mock, shim, stub, ....? I will opt for none of them thank you
I have a licensed third party API, it cost my company around 7,200€, and it was provided as part of an integration layer to a vendor application. The API provides me with a controlled and vendor supported mechanism to automate and query the data repository of the vendor application. The API technology is COM, methods are not exposed via. interfaces (so public instance and public static methods), all the modules are tightly coupled, and documentation on the API error codes and functionality are not particularly well documented.
I need to mock-, shim-, stub-, fake- whatever out the vendor API for two reasons. Firstly I need to write Unit Tests for my code (the classic case for the use of mocks etc). Secondly I need to provide a client with a working stand-alone (ie. isolated from/not connected to the remaining dependency tree and interconnected applications abstracted by this API) version of an application for UAT and milestone payment purposes.
Put another way, I need to implement the minimal behaviour of the real API object devoid of external dependencies, where it doesn’t communicate with vendor database and servers but simulates the API behaviour under a small controlled set of conditions. Mocking out one or two of API calls leaving the remainder intact is the goal. Dozens of mocking frameworks exist for this very purpose – none of this is new. Unfortunately mocking out only selected API methods and retaining the remainder of the API library is also the flaw in my thinking. If I were to distribute a copy of my licensed API, albeit with mocked methods, I breach the licence agreement.
The obvious solution is for my client to license their own copy of the product and API, or acquire a trial version, so the API and dependencies are legally available to all parties. The former requires 7,200€ and won’t fly in the budget just now and the latter is not offered by the vendor.
What shall I do? The second obvious solution is for me to write a limited simulator for the API mimicking the behaviour of the real object. Call it in-part a facade – for each vendor API method method that I invoke, I implement some piece of simple code that returns a predetermined response. Obviously the functionality I would implement would be minimal, but it would circumvent the issue of distributing the licensed API. I can even use tooling that would recursively replicate the public methods of the vendor API for me, then fill in the detail with a bit of home rolled code post hoc. This approach seems sound – for development, test, and project milestone delivery purposes; I develop against a limited library simulator, and upon completion, swap out my library for the real McCoy.
The approach is fraught with danger however, and not that from the technical perspective, but on the basis of copyright. The bottom line is that should I replicate the API public methods/interface, I might be in breach of copyright, but my concern is not so much whether I am in breach or not, but more to do with being taken to the cleaners having to argue my position. Is there precedent for API copyright and protracted legal expense? Yes there is, the high-stakes case of Oracle vs. Google has been rumbling on for years (some very readable background to the case can be found on SmartBear, the Register recently published an article titled “Your roadmap to the Oracle vs. Google Java Wars – Is it happening again” too) for example. Whether an API can be copyrighted or not the question – the question is one of risk management, and can I afford to defend myself irrespective of whether I believe I am on sound ground or not.
My only solution, the risk averse approach, is for me to write a object simulator for the vendor API (no, they do not provide one), but with a vastly different API, a facade API (so importantly not an adapter, just to be clear on the design-pattern difference between an adapter and a facade). I will have to write code twice too: a) one mock object will implement the facade interface and functionality I need to develop to return controlled and predetermined responses for development, testing, milestone delivery and so on (known as a test double in the jargon), b) to wrap the vendor API using the new facade interface. If I do it properly, when the time comes, I will be able to swap one library in, one out, with no change to the remainder of the codebase either. Perhaps I can even do this properly with a DI [NInject is my current favourite; nice and lightweight yet fully functional (and Packt offer an exceptionally cheap by-example book too if you wanted to take a gander)] mapping file so there are no change to the application binaries. Regardless however, so much for mocking and stubs, ….., and the general satisfaction of knowing that I have thought about writing a piece of well designed software using modern practices, this approach is about ensuring I do not need to contact a solicitor. This is important.
— Published by Mike, 10:26:02 09 December 2017 (CET)