Unit Testing for SharePoint Applications
The introduction to the Application Foundations chapter identifies several reasons why you should avoid writing classes that have direct dependencies on other services. It introduces various patterns that you can use to avoid direct dependencies in your code and provides links to more information about these patterns. One of the key reasons for removing direct dependencies is to make your classes suitable for unit testing. The previous section describes how unit testing involves isolating specific components of your code, usually individual methods, to be able to verify that the code under test provides expected outputs in response to known inputs. This section describes how unit testing actually works for SharePoint applications.
Suppose you want to design a Web Part that enables users to view and query product details from a catalog. In a rough, proof-of-concept approach, you might create a Visual Web Part and put all your logic in the code-behind file for the user control. However, this makes it almost impossible to unit test your business logic. Your code is tightly coupled to the user interface, the SharePoint environment, and the data source. To make your logic testable, there are several design changes you can introduce:
- Use the Model-View-Presenter (MVP) pattern to isolate your business logic from the user interface and the data source. You create a view class to render your user interface and a repository, or model, class to interact with your data source. All your business logic goes in the presenter class.
- Implement interfaces for your view classes and your services (such as repository classes). This enables you to replace the real classes with a fake class, typically known as stub classes or mock classes. Later sections describe these concepts in more detail.
- Use the Service Locator pattern to decouple your presenter class from specific implementations of the services that your presenter uses (such as your repository class). This provides an "interception" point where you can replace the real implementation that your presenter depends on with a fake implementation during test execution.
The following diagram illustrates this approach. You can view this test in the Partner Portal reference implementation in the Developing SharePoint Applications release.
Designing Web Parts for ease of testing
Let's review what happens when you unit test the ProductDetailsPresenter class. First, you develop two fake classes, the MockProductDetailsView and the MockProductCatalogRepository. The first class, MockProductDetailsView, implements the view interface. The test creates an instance of the MockProductDetailsView class. The view class instantiates the presenter class, and then it passes itself as the argument to the constructor for the presenter class. This approach is known as constructor injection**.** However, the test still needs to replace the actual repository class with the mock repository class. To achieve this, the test configures the service locator to return the test implementation to the presenter. The end result is that the presenter executes its logic without ever knowing that it is using fake implementations of the view and the repository.
The MVP pattern is a variation of the well known Model-View-Controller (MVC) pattern. In the client reference implementation, we use another variation of MVC called Model-View-ViewModel (MVVM). MVVM provides a similar isolation of user interface from business logic, but more closely fits the way that Silverlight and Windows Presentation Framework (WPF) work. It's also designed to take advantage of the rich binding capabilities and asynchronous eventing mechanisms available with these technologies. For more information, see the Client reference implementation.
Note
For a more detailed end-to-end view on how to apply unit testing to SharePoint, together with guidance on the design patterns that you can use to isolate code, see the section, Improving Application Quality Through Testing, in the Developing SharePoint Applications release. The Developing SharePoint Applications release was produced for Microsoft Office SharePoint Server 2007, but the patterns and testing approaches described are equally relevant to SharePoint Server 2010.