Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Unit Testing using Moq, NUnit and Shouldly

0.00/5 (No votes)
29 Nov 2015 1  
Unit Testing .NET applications using Moq, NUnit and Shouldly

Introduction

Today, when applications are getting more and more complex, it is very difficult for a developer to check all scenarios while creating or editing functionality. Therefore, a separate Unit Testing project is a must to make sure all desired functional parameters are met and nothing is being missed. To make it happen, sometimes data is mocked and conditional asserts are applied to validate the functional requirement. This tip is going to throw some light on how to implement unit testing into a .NET application using Moq, NUnit and Shouldly.

Background

NUnit has been there for a long time but some critical must have functionalities were missing viz data mocking where response from some external functionality is to be mocked using Moq to test a given functionality and Shouldly to make asserts more understanding and meaningful.

Both Moq and Shouldly are available as nuget packages.

Using the Code

To show how Mocking for a function is done, Moq is used to setup a given function to return predefined responses based on certain conditions.

Shouldly provides readymade wrapper functions to assert acceptable conditions.

[Test]
public void TestGetRailwayStationById()
{
    var mockClassBll = new Mock<IBll>();
    mockClassBll.Setup(c => c.GetRailwayStationById(It.IsAny<int>()))
        .Returns(new RailwayStationDs(1, "New Delhi"));
    var objRailwayStation = new RailwayStation(mockClassBll.Object);
    var result = objRailwayStation.GetRailwayStationById(1);
    result.ShouldNotBeNull();
    result.StationName.ShouldNotBeEmpty();
}

[Test]
public void TestGetRailwayStationByString()
{
    var mockClassBll = new Mock<IBll>();
    mockClassBll.Setup(c => c.GetRailwayStationByName(It.IsAny<string>()))
        .Returns(new RailwayStationDs(1, "New Delhi"));
    var objRailwayStation = new RailwayStation(mockClassBll.Object);
    var result = objRailwayStation.GetRailwayStationByName("New Delhi");
    result.ShouldNotBeNull();
    result.StationId.ShouldBeGreaterThan(0);
}

Unit Test Complex Functions with Saved Input Parameters and Output

In applications, there are few very complex functions which return different results based on lot of cases within them and it is very difficult to check all those cases, therefore the best way to unit test such functions would be to save all input parameters and their expected outputs. Such test data can be saved either in database or in XML files and can be used again and again during unit testing to validate all cases. Such test data is best suited for conditions when such complex functions are edited and unknowingly one or more case’s functionality alters and returns wrong result.

[TestMethod]
[DataSource("System.Data.SqlClient", 
@"Data Source=SAURABH\ADVANCE;Initial Catalog=TestDB;
Integrated Security=True", "dbo.StatusTestData", 
DataAccessMethod.Sequential)]
public void TestStatusDataDrivenSQL()
{
    TestContext.ShouldNotBeNull();
    var strTime = TestContext.DataRow["Time"].ToString();
    var varTime = TimeSpan.Parse(strTime);
    var varStatus = TestContext.DataRow["Status"].ToString();
    var objBll = new ClassBLL1();
    var result = objBll.CurrentStatus(varTime);
    result.ShouldNotBeNullOrEmpty();
    result.ShouldBe(varStatus);
}

[TestMethod]
[DeploymentItem(".\\UnitTestBLL\\XMLTestCases.xml")]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", 
@"XMLTestCases.xml", "case", DataAccessMethod.Sequential)]
public void TestStatusDataDrivenXML()
{
    TestContext.ShouldNotBeNull();
    var strTime = TestContext.DataRow["Time"].ToString();
    var varTime = TimeSpan.Parse(strTime);
    var varStatus = TestContext.DataRow["Status"].ToString();
    var objBll = new ClassBLL1();
    var result = objBll.CurrentStatus(varTime);
    result.ShouldNotBeNullOrEmpty();
    result.ShouldBe(varStatus);
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here