ASP.NET MVC Unit Tests with UnityAutoMoq Container

Posted by: Raj Aththanayake , on 10/17/2011, in Category ASP.NET MVC
Views: 79995
Abstract: In this article, we will explore UnityAutoMoq container, and how we can use this container to write maintainable ASP.NET MVC Unit Tests.

In this article, we will look at the usage of UnityAutoMoq container, and how we can use this container to write maintainable ASP.NET MVC Unit Tests. UnityAutoMoq container is an Open Source library, created by Thomas Pedersen. If you are new to Auto Mocking, please refer to this article, which briefly describes the concept.

You can also download the UnityAutoMoq via Nuget Package Manager.

Command: PM> Install-Package UnityAutoMoq

UnityAutoMoq container is based on Unity Dependency Injection (DI) framework, and Moq isolation/mock object framework. In this article, I assume that you already have some basic understanding of these frameworks, Dependency Injection, and ASP.NET MVC in general.

Most applications with DI containers and Isolation frameworks can utilize the Auto Mocking concept. However, in this article we will use ASP.NET MVC, since it is a great candidate to show some of the abstractions that the container hides during Unit Testing.

One of the key aspect of Auto Mocking is to abstract away the unnecessary mocking and stubbing, when writing Unit Tests. As a result of this, you would only spend less time on setting up expectations within Unit Tests. This is also an indication that Unit Tests become more maintainable, and easier to refactor during the system changes. For example, if dependencies have changed within the System Under Test (SUT), then there will probably be less refactoring on Unit Tests. This is because the Auto Mocking container has already abstracted away the additional dependencies for you. We will see few more examples, later in this article.

 

Stubbing HttpContextBase

When it comes to ASP.NET MVC Unit Testing, it is very common that we would have to stub HttpContextBase abstract class. We often have to setup expectations for stub versions of Http abstract classes such as Request, Response, Session, and Server etc. For example, you probably have already familiar with Unit Tests like below.

Note: The variable name ‘sut’, is the abbreviation for “System Under Test”.

http-context-base

figure 1

Below is a sample implementation of AccountController’s, LogOn() Action method. (SUT)

Note: I have simplified the implementation for demonstration purposes

account-controller-logon

figure 2

Now let’s debug the Unit Test in figure 1, and add the “context.Object” variable to a Watch window. We should see the value of HttpContextBase and the values of its properties as below.

moq-proxy

figure 3

Note: Red arrows indicate the Moq generated proxy types.

Since we have explicitly stubbed HttpContextBase and HttpRequestBase, Moq has generated proxies for HttpContext (context.Object), and Request as expected.

As you see in the Unit Test (figure 1), in order to stub the HttpRequestBase, we also had to stub HttpContextBase, HttpRequestBase, set the expectation for the HttpContext to return the stubbed Request, and assign the context to the ControllerContext. If we can just stub the ControllerContext and let the framework to automatically stub the additional dependencies, our Unit Test becomes much simpler and easier to read. With UnityAutoMoq container, we can achieve the same result with few lines of code. Please see below.

unity-moq-container

figure 4

Initialization of the UnityAutoMoq container can also be done outside the Unit Test method. For example in a factory method, setup method, or a Test Initialization method.

By resolving the ControllerContext, the container ensures those additional properties of ControllerContext, and their cascading counterparts, have either fake proxies been generated or instances created and available within the test execution context. Please see below.

unity-controller-context

figure 5

Let’s examine the implementation of Container.Resolve<T>().

Container.Resolve<T>()

As you see in figure 5, we have used the UnityAutoMoq’s container.Resolve<T>() method to resolve an instance of the ControllerContext. The Resolve<T>() returns an instance of the type specified by the type parameter T. The returned instance is not an object of the Moq.Mock<T> type. Therefore we cannot perform any setups or expectations on the returned instance. For concrete types (i.e. non-interface or non-abstract types), the Resolve<T>() returns concrete instances. In this example, ‘ControllerContext’ is a concrete type. If T is an abstract or an interface type, then the Resolve<T>() returns a proxy instance (Moq generated) of the type defined by the Type parameter T.

On a very high level, here’s how the Resolve<T> method internally works.

container-resolve

figure 6

As you see in figure 6, Resolve<T> also makes a call to the UnityContainer’s Resolve method.

During the Unity Container’s Resolve method execution, a custom Builder Strategy implemented by the UnityAutoMoq container, generates proxy instances for the types (i.e. abstract and interface types) resolved via the Unity Container. As a result of this, the ControllerContext properties such as HttpContextBase and its abstract/interface properties have proxy instances generated and available within the test execution context.

Below is the Watch Window on “controllerContext.HttpContext”

watch-window

figure 7

Note: Red bullets indicate the proxies generated by UnityAutoMoq.

As you can see in the above Watch window, Http abstract properties have proxies been generated and available within the test execution context. This is very beneficial in cases where we introduce additional dependencies (dependencies that are not part of our Unit Test), into the SUT. For example, let’s introduce the Profile Providers into the SUT (see figure 8).

profiler-providers

figure 8

Since the UnityAutoMoq container has proxies already generated, our Unit Test doesn’t require any further refactoring at all.

What if we want any of the stubbed properties to return a user defined/specific value?

We can still override the default proxies created by UnityAutoMoq container. For example, if we want the Request object to return null, then we can explicitly specify the expectation as below.

user-defined-stub

figure 9

Whenever the SUT expects the Request, the above setup will ensure the request object returns as null.

Note: This Unit Test will now fail, as we get an EmptyResult.

Container.GetMock<T>

Note that in figure 9, we have used ‘container.GetMock<HttpContextBase>()’ to create a Moq generated, Mock<HttpContextBase> object. The standard Moq framework can also generate a Mock<T> type object. For example, direct instantiating of the Mock<T> instance – ‘new Mock<T>()’. However, the implementation of ‘container.GetMock<T>()’ is different to the standard instantiation of Moq’s ‘new Mock<T>()’.

Below ‘mock1’ and ‘mock2’, both have the same return type, which is Mock<ISomeService>. However, the instances returned are different.

var mock1 = new Mock<ISomeService>();

and

var mock2 = container.GetMock<ISomeService>();

get-mock

figure 10

As you see in figure 10, the Container.GetMock<T>() also calls the Resolve<T>() method. Resolve<T>() returns an instance of the type defined by the type parameter T. We have already discussed the implementation of Container.Resolve<T>() before. The returned instance is then wrapped by the type Moq.Mock<T> object. Therefore we can now specify any setups or expectations on the returned Mock<T> type.

Stubbing HttpContextBase Alternatives

Also consider that fact that some developers also use non-Auto Mocking approaches to fake HttpContext. This includes hand written mocks/stubs, or helpers such as MVCMockHelpers. By using the UnityAutoMoq container you can further be productive as it allows you to fake dependencies without any additional code.

Action Filter and UnityAutoMoq container

In this next section, we will look at a more comprehensive example, where we can use the UnityAutoMoq container to Unit Test an ASP.NET MVC Action Filter.

The below Action Filter logs user information, passed via a ‘UserInfo’ object, to an ILoggerService service.

action-filter-log

figure 11

Let’s say we want to ensure that LoggerService.Log() method is called only once. Using the standard Moq API, we would write a Unit Test like this.

log-service-moq

figure 12

As you can see above, the ILoggerService is mocked so we can verify whether the Log() method is called. The setup on the stubbed IUserInfoService ensures we return a UserInfo object for the method GetUserInfo(). ActionExecutingContext is stubbed, so the instance can be passed as an argument to the OnActionExecuting method. We also have a setup on IsAuthenticated property to return ‘false’. Finally, we have stubs and setups on HttpContextBase, IPrinciple, and IIdentity types to return the appropriate instances.

By using the UnityAutoMoq container, we can further reduce the number of lines of code and additional stubbing/setups as below.

Note: The below example assumes, the UnityAutoMoq container has already been instantiated outside the Unit Test method.

unity-auto-logger-moq

figure 13

As you see above, ILoggerService is required to be mocked. This is because our Unit Test is to verify against the mock - ILoggerService. IUserInfoService and ActionExecutingContext are also stubbed to provide canned answers for the LogFilterAttribute.

Below are the key differences from the non-auto mocking version:

a. There is no setup on IUserInfoService to return a fake UserInfo object.

b. There are no stubs and setups for HttpContextBase, IPrinciple and IIdentity types.

Auto Mocking UserInfo object:

Let’s setup a breakpoint where we check the ‘userInfo’ object is not null – see figure 14. When we debug, we can see that UserInfo object has a proxy generated instance by the UnityAutoMoq container. This is because the UnityAutoMoq container automatically generates a proxy object (using Moq) for the returned type of IUserInfoService.GetUserInfo().

auto-mocking-userinfo

figure 14

This also assumes that UserInfo object does not have a parameterized constructor. If the UserInfo object has a parameterized constructor, then we would have to explicitly setup the expectation as below.

userInfoService.Setup(u => u.GetUserInfo()).Returns(() => new UserInfo(“userName”));

If the UserInfo object is expected to return null, then we would also have to explicitly setup an expectation as below.

userInfoService.Setup(u => u.GetUserInfo()).Returns(() => null);

Auto Mocking ActionExecutingContext:

The below figure shows the ActionExecutingContext resolved via the UnityAutoMoq container.


action-executing-context

figure 15

As you see in the above figure, proxy instances have been created for the properties of ActionExecutingContext. By resolving the ActionExecutingContext via container.Resolve<T>, the container also generates proxy instances for types such as HttpContextBase, IPrinciple etc. This is because the base class of ActionExecutingContext, which is the ControllerContext, and the container creates proxy instances for those additional types within ControllerContext. We have looked at a very similar cascading fake instances creation on ControllerContext before in figure 5.

Resolving the LogFilterAttribute

log-filter-attribute

figure 16

As you see in figure 16, we have introduced Unity’s [Dependency] attribute. At run time, the [Dependency] attribute allows us to inject dependencies to the system that they consume. These dependencies must be registered with IUnityContainer.

With the UnityAutoMoq container, the [Dependency] attribute becomes very handy as we can now automatically inject dependencies into the SUT, without having to explicitly inject them from our Unit Test.

For example in figure 13, we created the LogFilterAttribute as below.

var sut = new LogFilterAttribute { LoggerService = loggerServiceMock.Object, UserInfoService = userInfoService.Object };

In order to benefit from the [Dependency] attribute, we can now change the LogFilterAttribute to resolve via the UnityAutoMoq container.

For example:

var sut = container.Resolve<LogFilterAttribute>();

The above code injects proxy instances for both ILoggerService and IUserInfoService into the SUT.

The modified Unit Test now looks like the one shown below.

modified-unit-test

figure 17

In figure 17, you might have noticed that even though resolving the LogFilterAttribute enables us to automatically mock and inject the ILoggerService, we still have the ILoggerService explicitly being mocked. This is because we still require a mock so we can perform the verification against the mock.

If you look at it closely, it is also a bit odd that the instance returned from the container.GetMock<ILoggerService>(), which is the loggerServiceMock, is not really exercised within the SUT. What is really exercised is the mocked instance, that is automatically generated by resolving the LogFilterAttribute and injected via the [Dependency] attribute. So are we verifying against the wrong mock here? Even though it seems like the case, it turns out to be that both loggerServiceMock.Object and the sut.LoggerService refer to the same mocked instance. For example, their hash codes are exactly the same. Therefore the ILoggerService mocked instance, which is retrieved via the container.GetMock<ILoggerService>(), is the same instance, which we injected via the container.Resolve<LogFilterAttribute> and the [Dependency] attribute.

As we discussed before, container.GetMock<T>(), also calls the container.Resolve<T>() (figure 10). Therefore the mocked instance created by the UnityAutoMoq container’s custom builder strategy, gets reused and injected to the SUT during the call to container.Resolve<T>(). This is why we verify against the same mocked instance and the Unit Test passes as expected.

UnityAutoMoq container and Resolver Overrides

One of the cool new features of Unity 2 is the ResolverOverrides. There are few types of overrides such as ParameterOverride, PropertyOverride, and DependencyOverride etc. You may use any of these overrides with the UnityAutoMoq container. However, for the purpose of this exercise, we will only look at the ParameterOverride. Using the ParameterOverride, we can inject parameters to a constructor at the moment we resolve the type.

Let’s say our LogFilterAttribute class has a parameterized constructor, which accepts a string argument ‘name’. Please see the image.

log-parameter-constructor

figure 18

If we were to run the same Unit Test which we ran before with the UnityAutoMoq container, then we get a “ResolutionFailedException” on the line below.

resolution-failed-exception

figure 19

This is because the UnityContainer is unable to resolve the LogFilterAttribute as it is unaware of the new parameterized constructor. In order to make the container parameters aware, we can add a ParameterOverride by using a resolver override overload, provided by the UnityContainerExtensions.

parameter-override

figure 20

The LogFilterAttribute now contains the injected parameter as below.

log-filter-parameters
figure 21

Note: For simplicity and to focus on the override feature, we don’t do anything useful with the passed in constructor parameter.

The important bit here is that if we use the container.Resolve<T>() to create the SUT instance, as we did with LogFilterAttribute (figure 17), and if the SUT contains a parameterized contractor, then we can use the Resolver Overrides to inject dependencies as above.

Summary

UnityAutoMoq container is a great way to write maintainable Unit Tests. Since the container simplifies faking of dependencies, we can now focus on the actual test itself and spend less time on faking unwanted dependencies. It is also important to note that, when the SUT changes, refactoring on Unit Tests become lot easier. The benefits become apparent for ASP.NET MVC Unit Tests, as we can use the container to stub dependencies such as HttpContextBase, ActionExecutingContext etc. We also looked at few techniques where we can use the container to automatically inject dependencies into the SUT. Parameter Override provides the flexibility to inject parameters into the SUT via the container’s Resolve<T> method.

The entire source code of this article can be downloaded over here

Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Raj Aththanayake is a Microsoft ASP.NET Web Developer specializing in Agile Development practices such Test Driven Development (TDD) and Unit Testing. He is also passionate in technologies such as ASP.NET MVC. He regularly presents at community user groups and conferences. Raj also writes articles in his blog http://blog.rajsoftware.com. You can follow Raj on twitter @raj_kba


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Dan.Bellware on Friday, October 21, 2011 10:01 PM
Thanks for the excellent examples. The Automocking feature and using stubbed properties to return a user defined/specific value were very useful for my current project
Comment posted by Jalpesh Vadgama on Wednesday, May 23, 2012 2:15 AM
Nice work!!

Regards,
Jalpesh
http://www.dotnetjalps.com
Comment posted by Regards, Jalpesh on Friday, October 24, 2014 10:12 AM
Comment posted by Dan.Bellware on Friday, October 21, 2011 10:01 PM   
Thanks for the excellent examples. The Automocking feature and using stubbed properties to return a user defined/specific value were very useful for my current project
Comment posted by Jalpesh Vadgama on Wednesday, May 23, 2012 2:15 AM   
Nice work!!

Regards,
Jalpesh

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel