ASP.NET MVC Unit Tests with UnityAutoMoq Container

 

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

For more info, please refer to the article below.

http://www.dotnetcurry.com/ShowArticle.aspx?ID=767

Keeping your C# code clean with Regionerate

I came across with this really nice VS add-in called Regionerate, which allows you to group various member types into regions. I’m a fan of keeping code tidy and this add-in really helps me to organise the code.
It works on Visual Studio 2010 and only works with C#.
You can download the Add-In from here.
Once you install this tool, you are ready to use the Regionerate.
You can also change the settings of Regionerate, go to Tools and click Regionerate Settings.
To use the Regionerate, simply use the Ctrl +R. You should see a window with few options as below. Alternatively just right click on Text Editor and select ‘Regionerate this’ from the context menu.

image
image a

As per the above options, you can create regions based on the member types (I.e public, private, and internal), regionalise by the member name, regionalise by the member type and the member name, order the members without and regions, and remove existing regions etc..

Below is a code sample on selecting the ‘Primary Code Layout’.

I strongly encourage you to have a look at this Add-In as it is very useful.

Keeping your C# code clean with Regionerate

I came across with this really nice VS add-in called Regionerate, which allows you to group various member types into regions. I’m a fan of keeping code tidy and this add-in really helps me to organise the code.

It works on Visual Studio 2010 and only works with C#.

You can download the Add-In from here.

Once you install this tool, you are ready to use the Regionerate.

You can also change the settings of Regionerate, go to Tools and click Regionerate Settings.

To use the Regionerate, simply use the Ctrl +R. You should see a window with few options as below. Alternatively just right click on Text Editor and select ‘Regionerate this’ from the context menu.

image

 

As per the above options, you can create regions based on the member types (I.e public, private, and internal), regionalise by the member name, regionalise by the member type and the member name, order the members without and regions, and remove existing regions etc..

Below is a code sample on selecting the ‘Primary Code Layout’.

image

 

I strongly encourage you to have a look at this Add-In as it is very useful.

Returning Null from a generic method

A friend of mine asked me a question on this today. I hope you find this useful.
Consider this generic method….

 public T Get<T>() {
    //return null
    }

If you want to return null from a C# generic method, which contains the Type T parameter, there are 2 options.

a. Restrict the type parameter T, to be class constraint

 public T Get<T>() where T : class;
   {
      //return null
   }

Value types or Nullable Values types are not allowed. Reference types only.

b. Return default(T) which return null if T is a reference type or a Nullable value type

public T Get<T>()
   {
    return default(T);
   }

Anything else will simply return their default values. Here is a summary on both reference and value types….

//If T is a reference type

var retVal = f.Get<String>(); //return null

//If T is a value type - int
var retValInt = f.Get<int>(); //return 0

//If T is a value type - char
var retValChar = f.Get<char>(); //return '\0'

//If T is a value type - bool
var retValBool = f.Get<Boolean>(); //return false

//If T is a value type - enum
var retValEnum = f.Get<EnumType>(); // For enum types, if there are no enum values specified, then the return value is 0. If there are values, then the first enumeration returns as the default.

//If T is a value type - struct
var retValStruct = f.Get<Bar>(); //Structs, returns the value of the struct

//If T is a Nullable<Int32>
var retNullableInt = f.Get<Int32?>(); //return null

Returning Null from a generic method

 

Consider this generic method.

   1: public T Get<T>() { 

   2: //return null

   3: }

   4:  

If you want to return null from a C# generic method, which contains the Type(T) parameter, there are 2 options.

a. Restrict the type parameter T, to be class constraint

   1: public T Get<T>() where T : class;

   2: {

   3:    //return null

   4: }

   5:  

Value types or Nullable Values types are not allowed. Reference types only.

b. Return default(T) which return null if T is a reference type or a Nullable value type

   1: public T Get<T>()

   2: {

   3:   return default(T);

   4: }

   5:  

Anything else will simply return their default values.  Here is summary on both reference and value types….

//If T is a reference type

var retVal = f.Get<String>(); //return null

……….

//If T is a value type – int

var retValInt = f.Get<int>(); //return 0

……….

//If T is a value type – char

var retValChar = f.Get<char>(); //return ”

……….

//If T is a value type – bool

var retValBool = f.Get<Boolean>(); //return false

……….

//If T is a value type – enum

var retValEnum = f.Get<EnumType>(); // For enum types, if there are no enum values specified, then the return value is 0. If there are values, then the first enumeration returns as the default.

……….

//If T is a value type – struct

var retValStruct = f.Get<Bar>(); //Structs, returns the value of the struct

……….

//If T is a Nullable<Int32>

var retNullableInt = f.Get<Int32?>(); //return null

……….

Moq 4 and “LINQ to Mocks”

While searching for Moq code samples, I came across that Moq 4 was released few months ago. The key improvement was the new “LINQ to Mocks”.

This post demonstrates few examples of the usage of Mocks and LINQ queries. For each example, we stub out dependencies using lambda expressions first, and then see the corresponding LINQ version. At the end we see the performance of each Unit Tests.

Note: I’m using the xUnit Testing Framework. However you can apply the same principles to other Unit testing frameworks.

Single Stub

Lambdas:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse()

   3: {

   4:     //Arrange

   5:     var dbServiceStub = new Mock<IDbService>();

   6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(false);

   7:     var customerService = new CustomerService();

   8:     customerService.DbService = dbServiceStub.Object;

   9:

  10:     //Act

  11:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

  12:

  13:     //Assert

  14:     Assert.False(isUpdated);

  15: }

LINQ:

   1: [Fact]

   2:  public void UpdateCustomer_WhenCustomerIsNotUpdated_ReturnsFalse()

   3:  {

   4:      //Arrange

   5:      IDbService dbServiceStub = (from dbService in Mocks.Of<IDbService>() where dbService.Update(It.IsAny<Customer>()) == false

   6:                                  select dbService).First();

   7:      var customerService = new CustomerService { DbService = dbServiceStub };

   8:

   9:      //Act

  10:      bool isUpdated = customerService.Update(It.IsAny<Customer>());

  11:

  12:      //Assert

  13:      Assert.False(isUpdated);

  14:  }

 

Multiple Stubs

Lambdas:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue()

   3: {

   4:     //Arrange

   5:     var dbServiceStub = new Mock<IDbService>();

   6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(true);

   7:     var loggerServiceStub = new Mock<ILoggerService>();

   8:

   9:     var customerService = new CustomerService { DbService = dbServiceStub.Object, LogService = loggerServiceStub.Object };

  10:

  11:     //Act

  12:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

  13:

  14:     //Assert

  15:     Assert.True(isUpdated);

  16: }

 

LINQ:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_ReturnsTrue()

   3: {

   4:     //Arrange

   5:     var fakes = (from dbService in Mocks.Of<IDbService>()

   6:                  from loggerService in Mocks.Of<ILoggerService>()

   7:                  where dbService.Update(It.IsAny<Customer>()) == true

   8:                  select new { dbServiceStub = dbService, loggerServiceStub = loggerService }).First();

   9:

  10:     var customerService = new CustomerService { DbService = fakes.dbServiceStub, LogService = fakes.loggerServiceStub };

  11:

  12:     //Act

  13:     bool isUpdated = customerService.Update(It.IsAny<Customer>());

  14:

  15:     //Assert

  16:     Assert.True(isUpdated);

  17: }

Mocks and Stubs

 

Lambdas:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_VerifyLoggerServiceLogIsCalled()

   3: {

   4:     //Arrange

   5:     var dbServiceStub = new Mock<IDbService>();

   6:     dbServiceStub.Setup(d => d.Update(It.IsAny<Customer>())).Returns(true);

   7:     var loggerServiceMock = new Mock<ILoggerService>(); //We verify against the Mock

   8:     loggerServiceMock.Setup(l => l.Log(It.IsAny<string>())).Verifiable();

   9:

  10:     var customerService = new CustomerService()

  11:     {

  12:         DbService = dbServiceStub.Object,

  13:         LogService = loggerServiceMock.Object

  14:     };

  15:

  16:     //Act

  17:     customerService.Update(It.IsAny<Customer>());

  18:

  19:     //Assert

  20:     Mock.Get(loggerServiceMock.Object).Verify(c => c.Log(It.IsAny<string>()));

  21: }

LINQ:

   1: [Fact]

   2: public void UpdateCustomer_WhenCustomerIsUpdated_VerifyLoggerServiceLogIsCalled()

   3: {

   4:     //Arrange

   5:     var fakes = (from dbService in Mocks.Of<IDbService>()

   6:                  from loggerService in Mocks.Of<ILoggerService>()

   7:                  where dbService.Update(It.IsAny<Customer>()) == true

   8:                  select new { dbServiceStub = dbService, loggerServiceMock = loggerService }).First();

   9:

  10:     var customerService = new CustomerService { DbService = fakes.dbServiceStub, LogService = fakes.loggerServiceMock };

  11:

  12:     //Act

  13:     bool isSend = customerService.Update(It.IsAny<Customer>());

  14:

  15:     //Assert

  16:     Mock.Get(fakes.loggerServiceMock).Verify(c => c.Log(It.IsAny<string>()));

  17: }

 

Testing an MVC Action Filter

Lambdas:

   1: [Fact]

   2: public void OnActionExecuted_WhenEmployeeSalaryIsEqualToZero_ EnsureActionExecutedContextResultEqualToFilterResult()

   3: {

   4:     //Arrange

   5:     decimal employeeUnpaidAmount = 0.0M;

   6:     var employeeServiceStub = new Mock<IEmployeeService>();

   7:     employeeServiceStub.Setup(s => s.GetSalary()).Returns(employeeUnpaidAmount);

   8:

   9:     var filter = new EmployeeSalaryNotificationAttribute

  10:     {

  11:         EmployeeService = employeeServiceStub.Object

  12:     };

  13:

  14:     var actionExecutedContextMock = new Mock<ActionExecutedContext>();

  15:     var routeData = new RouteData();

  16:     routeData.Values.Add("fakeIdKey", "fakeIdValue");

  17:     actionExecutedContextMock.SetupGet(r => r.RouteData).Returns(routeData);

  18:

  19:     var request = new Mock<HttpRequestBase>();

  20:     var httpContext = new Mock<HttpContextBase>();

  21:     httpContext.SetupGet(c => c.Request).Returns(request.Object);

  22:     actionExecutedContextMock.SetupGet(h => h.HttpContext).Returns(httpContext.Object);

  23:

  24:     //Act

  25:     filter.OnActionExecuted(actionExecutedContextMock.Object);

  26:

  27:     //Assert

  28:     Assert.Equal((actionExecutedContextMock.Object.Result as ContentResult).Content, filter.SalaryResult);

  29: }

LINQ:

   1: [Fact]

   2: public void OnActionExecuted_WhenEmployeeSalaryIsEqualToZero_EnsureActionExecutedContextResultEqualToFilterResult()

   3: {

   4:     //Arrange

   5:     RouteData routeData = new RouteData();

   6:     routeData.Values.Add("fakeIdKey", "fakeIdValue");

   7:

   8:     var fakes = (from employeeService in Mocks.Of<IEmployeeService>()

   9:                  from actionExecutedContext in Mocks.Of<ActionExecutedContext>()

  10:                  where employeeService.GetSalary() == 0.00M &&

  11:                  actionExecutedContext.HttpContext == Mock.Of<HttpContextBase>() &&

  12:                  actionExecutedContext.HttpContext.Request == Mock.Of<HttpRequestBase>() &&

  13:                  actionExecutedContext.RouteData == new RouteData()

  14:                  select new { EmployeeServiceStub = employeeService, ActionExecutedContextMock = actionExecutedContext })

  15:                  .First();

  16:

  17:     var filter = new EmployeeSalaryNotificationAttribute

  18:     {

  19:         EmployeeService = fakes.EmployeeServiceStub

  20:     };

  21:

  22:     //Act

  23:     filter.OnActionExecuted(fakes.ActionExecutedContextMock);

  24:

  25:     //Assert

  26:     Assert.Equal((fakes.ActionExecutedContextMock.Result as ContentResult).Content, filter.SalaryResult);

  27: }

 

Key things to notice:

– The tests with LINQ queries reflect the test scenarios/conditions in a more of a specification style. This improves the tests readability.

– The query returns an infinite number of mocks. Typically we access the first element.

var fakes = (LINQ query).First();

– LINQ query result returns real object(s) and not the type Mock<T>. So we do not need to use the EmployeeServiceStub.Object. Instead we can just use the returned element.

EmployeeService = fakes.EmployeeServiceStub;

 

– When you have multiple stubs or mocks, you can return all of them using an anonymous type.

   select new { dbServiceStub = dbService, loggerServiceStub = loggerService }));

– Not used in these code samples, but if you are using the MockFactory class, it is now absolute in v4. MockFactory will be retired in v5.

 

Performances:

Here is a very quick benchmark results on each Unit Test.

Test

Lambda

LINQ

UpdateCustomer_WhenCustomerIsNotUpdated

_ReturnsFalse

0.95s

1.01s

UpdateCustomer_WhenCustomerIsUpdated

_ReturnsTrue

 

0.97s

 

1.06s

 

UpdateCustomer_WhenCustomerIsUpdated

_VerifyLoggerServiceLogIsCalled

 

0.94s

 

1.07s

 

 

OnActionExecuted_WhenEmployeeSalaryIsEqualToZero

_EnsureFilterResultContainsTheStringNotPaid

 

1.08s

 

1.29s

 

 

Unit Tests with LINQ queries take “tiny” bit longer than the Lambda counterparts. However, I would personally still use LINQ version as it improves the readability of Unit Tests.