Stubs and Mocks
So what do the terms stub classes and mock classes mean? In a unit test, you test one specific piece of code. If your code makes calls to other classes and external assemblies, you introduce complexity and uncertainty into the test—you do not know whether your code is failing the test or whether the dependency classes are behaving in an unexpected way. To remove this uncertainty, you replace the dependency classes with fake implementations. These fake implementations are known as fakes, mocks, and stubs. The nuanced differences between fakes, mocks, and stubs are not very important to this section, vary according to who you ask, and often evolve into complex discussions around topics such as behavioral and state-based testing. As your approach to testing becomes more sophisticated, these variations are good to understand. Mock has become a popular term and is often used today to represent any type of test class substituted for a real implementation. Fake is a more generic term in increasingly common use and has less controversy surrounding it, so the remainder of this section refers to these substitute test implementations as fakes.
Substituting classes that are required by the code under test is challenging. For example, your presenter class calls into your repository class. How do replace the repository implementation with a fake class without editing the presenter class? This is where service location (or a more sophisticated dependency injection approach) comes in. Your presenter class uses service location to get a repository implementation, and when you run the test, you configure the service locator to return your fake implementation instead.
Service location is driven by interfaces and interface implementations. To use service location, you must design your dependency classes to implement relevant interfaces. For example, by defining the IProductCatalogRepository interface as the basis for your repository class, and by calling IProductCatalogRepository methods from your presenter class, you make it possible to supply fake implementations of IProductCatalogRepository without editing your presenter logic.
Service location is an important concept for unit testing and for modular, flexible code in general. The SharePoint Guidance Library includes a SharePoint-specific implementation of the Service Location pattern that you can use in your own solutions. For more information, see The SharePoint Service Locator.
Using fake classes is straightforward if you create the dependency classes yourself, because you have full control over how they are implemented. It can be more challenging if you need to provide substitutes for external classes. The SharePoint object model is a case in point. SharePoint integration is problematic in unit tests for the following reasons:
- Most classes in the SharePoint object model do not implement interfaces or virtual methods that you can override to create substitute implementations.
- Many SharePoint classes are sealed with private constructors, so you cannot derive from them or even create them directly.
This makes these classes impossible to substitute with conventional mocking techniques. Providing substitute implementations of SharePoint classes for unit testing requires a more sophisticated toolset.
The Developing SharePoint Applications release demonstrated the use of a third-party product named TypeMock. This overcomes the limitations of conventional mocking by intercepting calls to SharePoint APIs and redirecting the calls to mock implementations. TypeMock continues to be a great choice for mocking functionality when you work with SharePoint Server 2010. This release adds another approach that can be used to overcome these limitations through the use of a framework named Moles.