Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

KickStart your Unit Testing using Moq

, 12 Jul 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
What is Moq ? Moq is a third party library/framework that enables you to create the dummy class and its methods’ dummy implementation without actually creating a class with actual method implementation. Here you need to note that you need to provide the interface name for creating dummy class

Editorial Note

This article appears in the Third Party Product Reviews section. Articles in this section are for the members only and must not be used by tool vendors to promote or advertise products in any way, shape or form. Please report any spam or advertising.

What is Moq ?

Moq is a third party library/framework that enables you to create the dummy class and its methods’ dummy implementation without actually creating a class with actual method implementation. Here you need to note that you need to provide the interface name for creating dummy class which will implement interface methods as dummy. This is very useful in the scenarios where you want to test the functionality of a class without implementing the other classes and their methods on which the test candidate class is dependent on.

How to install “Moq” in your test project ?

You can install “Moq’ in your test project using “NuGet Package Manager” UI or console. You can find “Manager NuGet Package” by right clicking on your project solution. When you click on it you will get a UI where you can search “Moq” online and install it to your test project. Now you are ready to go with using “Moq”.

How to use “Moq” in your project to test library classes?

Lets say that you have a class “DefaultMailer” which implements interface “IMailer” with method “SendMail”. SendMail needs an object, of type “IMailClient” as parameter, which will be used to actually send the mail.

Here, IMailer has only four properties, for simplicity, which are necessary to send mail.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YourNamespace.Utility.Interfaces
{
    public interface IMailer
    {
        string From { get; set; }
        string To { get; set; }
        string Subject { get; set; }
        string Body { get; set; }

        bool SendMail(IMailClient mailClient);
    }
}

IMailClient has only one methods which is used to send mail. It has only two properties i.e. Host and port. Here you can have many MailClients for supported mail servers like gmail, yahoo, hotmail etc.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YourNamespace.Utility.Interfaces
{
    public interface IMailClient
    {
        string Server { get; set; }
        string Port { get; set; }

        bool SendMail(string from, string to, string subject, string body);
    }
}

DefaultMailer implements IMailer interface.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YourNamespace.Utility.Interfaces;

namespace YourNamespace.Utility
{
    public class DefaultMailer : IMailer 
    {
        public string From { get; set; }
        public string To { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }

        public bool SendMail(IMailClient mailClient)
        {
            return mailClient.SendMail(this.From, this.To, this.Subject, this.Body);
        }
    }
}

Now we will see how to test if your DefaultMailer > SendMail method is working as expected. To do this, create a UnitTest project in your solution and install Moq using NuGet package manager. Create a UnitTest class as below.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using YourNamespace.Utility.Interfaces;
using YourNamespace.Utility;
using Moq;
using Moq.Matchers;

namespace YourNamespace.Utility.TestFixtures
{
    [TestClass]
    public class MailerTestFixtures
    {
        [TestMethod]
        public void SendMailTestFixture()
        {
            //Create a mock object of a MailClient class which implements IMailClient
            var mockMailClient = new Moq.Mock<IMailClient>();

            //Mock the properties of MailClient
            mockMailClient.SetupProperty(client => client.Server, "chat.mail.com").SetupProperty(client => client.Port, "1212");

            //Configure dummy method so that it return true when it gets any string as parameters to the method
            mockMailClient.Setup(client => client.SendMail(It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>())).Returns(true);

            IMailer mailer = new DefaultMailer() { From = "from@mail.com", To="to@mail.com", Subject="Using Moq", Body="Moq is awesome"};

            //Use the mock object of MailClient instead of actual object
            var result = mailer.SendMail(mockMailClient.Object);

            //Verify that it return true
            Assert.IsTrue(result);

            //Verify that the MailClient's SendMail methods gets called exactly once when string is passed as parameters
            mockMailClient.Verify(client => client.SendMail(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
        }
    }
}

Now I will explain the syntax of Moq I have used in the above test case. This is the most simple test case you can use. I have kept it simple here so that you can at least get started with its basics without worrying about the other complex syntax of Moq.

Creating the object of dummy class which implements an interface.

//Create a mock object of a MailClient class which implements IMailClient
var mockMailClient = new Moq.Mock<IMailClient>();

In this example, I have created dummy class which implements the interface IMailClient. The result would be a factory which will give me object of this dummy class by using its property Object.

Setup the properties of dummy class as per your need.

/Mock the properties of MailClient
mockMailClient.SetupProperty(client => client.Server, "chat.mail.com")
              .SetupProperty(client => client.Port, "1212");

You can set the default value for the properties of your dummy class objects using the “SetupProperty” provided by Moq.

Setup the methods of dummy class as per your need.

//Configure dummy method so that it return true when it gets any string as parameters to the method
mockMailClient.Setup(client => client.SendMail(It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>())).Returns(true);

Here we are setting up the SendMail method of your dummy class.  The meaning of the statements is that “When someone invokes the method “SendMail” of dummy class object with four parameters, which may be any string value, then return true. You can modify the statement to configure the cases where user passes null or empty or particular string.

Use the mock/dummy object to test your class “DefaultMailer”

//Use the mock object of MailClient instead of actual object
var result = mailer.SendMail(mockMailClient.Object);

//Verify that it return true
Assert.IsTrue(result);

Here we are using the object of mock/dummy class instead of actual IMailClient implementation. The reason behind this here is that we need to test our class “DefaultMailer” without depending on any other classes. We should assume here that other classes are working fine as we should have written separate test cases to test them.

Verify that the particular method of the interface was invoked

//Verify that the MailClient's SendMail methods gets called exactly once when string is passed as parameters
mockMailClient.Verify(client => client.SendMail(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once);

Here we verify that the method of the client was actually invoked by DefaultMailer to send mail. We also ensure that the method was invoked just once. In case, it was not invoked or invoked more than once then it will fail the test case.

You can learn more about Moq here.

Note: Here I have not concentrated on the design for actual implementation of MailClient or MailSender. I have kept it simple so that you can understand Moq without worrying about implementation of actuall MailClient or MailSender.

I hope it will be useful for you to start using Moq to test your methods without creating actual objects of dependency classes. You will learn about the syntax of Moq and get familiar with it as much as you practice. At first you will find it difficult because of its Action, Func, LINQ implementations but once you start using it, you will find it fun and proficient to use Moq.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Adarsh Chaurasia (Consultant|Mentor|Tech Savvy)
Software Developer (Senior)
India India
I have 4.6+ years of experience in SaaS, SOA based Enterprise Web Application design and development using Microsoft technology stack. I have mostly worked on Business layer, Data access layer, WCF, Entity Framework, Microsoft Application Blocks, Search engines, APIs integration, Third party APIs/Product Research & Development.
 
I am a huge fan of Design Patterns. I also work as Software Consultant. I read/write blogs, help and learn from other developers.
Follow on   Twitter   LinkedIn

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.141015.1 | Last Updated 12 Jul 2014
Article Copyright 2014 by Adarsh Chaurasia (Consultant|Mentor|Tech Savvy)
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid