In the previous blog post, I covered how to create and configure a JustMock Unit Test project for a new Sitefinity web application. After covering some key definitions for unit testing, a unit test project was added, and a boilerplate test class was created for testing a reindex search utility method in the SitefinityWebApp project. We will pick up exactly where we left off and add a test method to the recently created SearchTests class. By the end of the post we will have a set of tests that can be executed.
1) The SearchTests.cs file already contains some boiler plate code that you can add to if you want. For this walkthrough, throw a Reindex_CalledFromUtility_ReturnsTrue method into the class toward the bottom. In the test method, SearchUtility.Reindex(“index1”) is called and it will return “true” if the reindex succeeds and “false” if it does not. An Assert is added to check that it returns true. If the reindex fails for some reason then this test will also fail.
Thinking ahead, we know that this is likely going to be a problem because search indexes reside on the site as actual files, which is dependency we don’t want to maintain. The unit test should be able to run successfully in complete absence of those search indexes.
2) Run the test and it fails with plenty of references to the PublishingManager (which is used inside the SearchUtility.Reindex method). The solution for this error is to create mocks for all the portions of the code that rely on external elements.
3) Below is a snapshot of the Reindex method and all of its components that need to be mocked (i.e. doing db or service requests)
a. PublishingManager – what we use for fetching the search indexes.
b. Points – where we store the returned publishing points (essentially, the search indexes)
c. SystemManager.CurrentContext – static class returning the current site context
d. SystemManager.CurrentContext.IsMultiSiteMode - property returning whether the site is multi-site
e. SystemManager.CurrentContext.CurrentSite.Id – id of the current site
f. PublishingManager.Provider.GetSiteItems(siteId) – returns publishing point based on a site id (multisite)
g. PublishingAdminService – Service used for reindexing a search index
4) Once the components that need to be mocked have been identified, mocks can be initialized and arranged. The following screenshot creates and initializes the mocks for the components (matching on color) that we know need to be replaced with independent versions. This code is executed in an initialize method which gets executed once for all the test methods so each test does not need to create these mocks.
The mock objects are declared at the top and get initialized in “MyClassInitialize”. “Mock.Create” returns a mocked version of the service/manager/interface/class that it receives. In this case we use it for PublishingManager, SitefinityContextBase, ISite, PublishingDataProviderBase, and PublishingAdminService. Once these mocks are created, they are arranged to be used instead of the normal managers and services.
For example, when “PublishingManager.GetManager” is called with any string parameters, the mocked PublishingManager is returned instead of the real one. Likewise, when that mocked PublishingManager “GetPublishingPoints()” is called, it returns “publishingPoints.AsQueryable()” which we created in the test instead of having Sitefinity fetch it.
As the mocks get arranged, SearchUtility. Reindex becomes independent from the CMS dependencies.
5) Run the test now that everything has been mocked.
This time the test runs without throwing the exception, but still fails because the Assert expected true and SearchUtility. Reindex returned false. It failed because the Reindex method has now been mocked to function in the absence of any search index data. Calling “Reindex(“index1”)” asked the API to index “index1” without providing a mocked index to reindex, so it failed. If this is going to run successfully, a mocked index needs to be created.
Modify the test to the following:
Finally, this returns a passed result.
This can be taken a step further by adding two more tests to further cover the reindex functionality:
Each test passes with the newly mocked managers and services.
Now we have a “finalized” version of this test class running tests that validate this single utility method. This utility class is just one example of a unit of code that can be tested, and it’s a simple example on how to get up to speed with writing unit tests. Moving forward, we can use this unit test project for testing additional utilities and controls in the Sitefinity application.