Setup on the same method using MOQ

Someone asked me about this today and I thought of it is a useful tip to write a small post. See the below code. If you know how to setup the same method in such a way that it would not override during the test execution, you can stop reading the rest of the post. If not please see the below example.

    public class SomeClass
    {
        private readonly ISomeInterface _someInterface;

        public SomeClass(ISomeInterface someInterface){
            _someInterface = someInterface;
        }

        public string SomeMethod()
        {
            string str1 = "str1";
            string str2 = "str2";
            
           var r1 = _someInterface.DoSomething(str1, str2);
            var r2 = _someInterface.DoSomething(string.Empty, string.Empty);
            
            return "something";
        }
    }

Notice that the same method call twice with different parameters. In our Unit Test, if we were to stub these two methods, the second/last setup method overrides the first one. In other words both r1 and r2 has the value of “bar”. This is not what we expect as we want setup methods to behave differently and return different values for r1 and r2.

Couple of ways you can achieve this with Moq.

a. Using It.Is

You can specify a predicate that matches a specified criteria.

[TestMethod]
public void TestMethod3()
{
       var stub = new Mock<ISomeInterface>();
        stub.Setup(x => x.DoSomething(It.Is<string>
                     (s => !string.IsNullOrEmpty(s)), It.Is<string>
                     (s => !string.IsNullOrEmpty(s)))).Returns("foo");
        stub.Setup(x => x.DoSomething(It.Is<string>
                     (s => string.IsNullOrEmpty(s)), It.Is<string>
                     (s => string.IsNullOrEmpty(s)))).Returns("bar");
            
        var sut = new SomeClass(stub.Object);
        var r = sut.SomeMethod();
     }

b. This is the one that I like most as it only needs one setup and slightly quicker
Provide the delegate on the “Returns” that match the criteria.

[TestMethod]
 public void TestMethod2()
 {
       var stub = new Mock<ISomeInterface>();
       stub.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
                .Returns<string, string>((x, y) => {
                     if (x != string.Empty && y != string.Empty){ return "foo";}
                     if (x == string.Empty && y == string.Empty){ return "bar";}         
                     return string.Empty;
           });

       var sut = new SomeClass(stub.Object);

       var r = sut.SomeMethod();

   }

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

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.

Automating QUnit and JSTestDriver within VS2010

I briefly touched based on this during my presentation at Code Camp. There were number of developers who were interested in browser based Unit Testing. This blog post is to provide you with some information on how you would automate browser based Unit Testing with VS2010.

QUnit is a great JavaScript Unit Testing tool which allows you write powerful browser based Unit Tests. You can find more information on QUnit here.

As described in the JSTestDriver Getting Started, you can use the below command to run both Java server and the client using a single command.

java jar <path>/JsTestDriver.jar port 9876browser firefoxpath,chromepath –tests all

Next step is to automate the above command within VS2010. You can easily achieve this by using VS External Tools.

·         VS -> Tools -> External Tools ‘Add new’

·         Specify the Title E.g “Js Unit Tests Run”

·         Specify the Command – C:\Program Files\Java\jre6\bin\java.exe

(This is the path where your java runtime is located)

·         Specify the Arguments

-jar <path>/JsTestDriver.jar –port 9876 –browser  “C:\Program Files\Internet Explorer\iexplore.exe, C:\Program Files\Mozilla Firefox\firefox.exe” –tests all

·         Initial Directory is the path to the directory where the JSTestDriver is located.

·         Ensure you select the “Use Output Window” check box, so you can see the Unit Tests result in the output windows.

Once you run the VS external command, you should be able to see your output similar to below.

image

You can further automate this by running a VS macro, so every time when you save a JS file the above command will run all browser Unit Tests.

 

Code Camp OZ2010 – Real World Unit Testing & Future

I hope you all had a great time at Code Camp and a safe journey back home.

This blog post is to provide you with some additional references on the presentation Real World Unit Testing & Future. I have also included some answers to the questions which some of you have had after the presentation. At the end of this post, there is a link and you can download my presentation slides. 

Download TestLint http://site.typemock.com/test-lint/

Links to Roy Osherove’s Test Reviews.

Unity : http://weblogs.asp.net/rosherove/archive/2009/03/23/test-review-3-unity.aspx

ASP.NET MVC : http://weblogs.asp.net/rosherove/archive/2009/03/21/test-review-2-asp-net-mvc-unit-tests.aspx

Question on multiple Asserts in a Unit Test?

Post presentation questions interested me that some of you have different opinions on having multiple asserts within a Unit Test. The point I wanted to make was, as a general rule, it is best to have one assert per Unit Test.  Having said that, there may be instances where you would like to test logically related things within the same Unit Test.  Which means “Multiple aspects of the same object”. If one aspect fails then we would consider as the Unit Test is fail. 

        [TestMethod]
        public void TraceOutput_SimpleStringWithCommaDelimitted_AnalyseTraceData()
        {
            TraceAnaliser traceAnaliser = new TraceAnaliser();

            AppTraceOutput traceOutput = traceAnaliser.AnalyseTraceData("Europe, Africa, 10:00, Australia, Simon");

            //Different aspects of the same object being tested.
            Assert.AreEqual(traceOutput.ReadLine(1)[0], "Europe");
            Assert.AreEqual(traceOutput.ReadLine(1)[1], "Africa");
            Assert.AreEqual(traceOutput.ReadLine(1)[2], "10.00");
            Assert.IsTrue(traceOutput.LineCount == 1);
        }

If you want to make the above test more maintainable you would also consider comparing the objects. For example…

Assert.AreEqual(traceOutput, expected);

Having multiple asserts in Unit Tests raise maintainability issues. If the first assert fails, then the subsequent asserts will never get executed.  We would never know those subsequent asserts were succeeded or not.  Since it is a partial picture, sometimes it is very hard to isolate the problem why the Unit Test is failing. If the tests are separated and solid they are easier to read and easier to maintain.

Also I came across with another tool (NUnit Addin for Running one assert per test ) which I did not include in my talk, but please feel free to have a look at this.

http://rauchy.net/oapt/

The difference between the Code Contracts and Unit Tests.

There was a question on Code Contracts and Pex. Code Contracts allows you to perform powerful assertions within your production code. It encapsulates the intention of your design using contracts, so the compiler tools using Static Analysis, Runtime Analysiscan be used to discover those intentions (E.g Pre Conditions and Post Conditions). Unit Test, verifies a piece of logic/behaviour within a method while allowing you to improve the design of the production code. One cannot replace each other as they both have different purposes.

Download Code Contracts and Pex

Code Contracts – http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx

Pex – http://research.microsoft.com/en-us/projects/pex/

Where can I get more information on Code Contracts and Pex?

Here is a video from PDC 2010 which explains some useful information using Pex and Code Contracts. http://channel9.msdn.com/Blogs/martinesmann/Code-Contracts-and-Pex-Power-Charge-Your-Assertions-and-Unit-Tests

Download Sinon, JSTestDriver and QUnit

a.      Sinon – http://cjohansen.no/en/javascript/javascript_test_spies_stubs_and_mocks

b.      JSTestDriver – http://code.google.com/p/js-test-driver/

C.      QUnit – http://docs.jquery.com/Qunit 

d.   QUnit to JSTestDriver adaptor – http://code.google.com/p/js-test-driver/wiki/QUnitAdapter

(Note : I will soon write a separate blog post on how to automate this within VS 2010)

Powerpoint slides. Real world Unit Testing & Future.pptx (971.90 kb)

Code Camp 2010 – Real world unit testing from David Burela on Vimeo.