Should you mock it or fake it? That’s a question you probably find yourself asking when designing a software testing strategy.
It isn’t always easy to decide which mock framework is best for testing your code. For developers using Microsoft Visual Studio, the most basic choice is whether to use VS’ built-in Microsoft Fakes framework, or a third-party/open source framework such as Moq or NSubstitute. In this post, we’ll take a look at what makes MS Fakes stand out from other mock frameworks, and when Fakes may or may not be your best choice for testing.
The Real Fake Story
First, though, some background – what are mock frameworks, and why would you use them? In many ways, mock frameworks are simply extensions of traditional testing techniques, updated for object-oriented programming.
The basic problem that mock frameworks are designed to solve is this: When you’re testing code that is still in development, you need to be able to test its interaction with dependencies, with outside applications, and with system resources, but it is not always possible to do so. Very often, the dependencies are still under development, or have not been created, and even when your code is interacting with external programs or system components, the tests may require a set response (such as a specific time of day or error code) which the application or resource cannot be counted on to supply.
A mock framework allows you to supply realistic emulations of the required interactions by means of mocks, stubs, and shims. (Note that these terms do not always have clear, agreed-upon definitions, and are sometimes used interchangeably – here, we will try to remain consistent with reasonably widespread definitions and use.)
Making the Right Kind of Mockery
Mocks interact with the code being tested by means of interfaces. This means that in order to use mocks for testing, you must write code that is fully interface-compliant. A mock stands in for the object which it represents. From the point of view of the unit being tested, there should be no difference between a mock and the actual object.
A mock, however, does not need to duplicate the internal operations of the object that it represents. Instead, it can return hard-coded responses (always sending back “True” or “Smith, J.Q.”, for example), or it can contain logic designed to test the unit in more sophisticated ways (by using assertions, or by emulating complex behavior on the part of a client, for instance).
A stub is also interface-based and is in many other ways similar to a mock. In practice, the distinction between them is not always clear. In general, however, the main function of a stub is to stand in for an object by returning hard-coded values as if it were that object. A stub may include simple assertions, but it typically will not include the kind of complex test logic which is often used by mocks.