In this article, we are going to learn about mocking with the Moq framework for .NET. Specifically, we’re going to learn how we can mock a method, which returns a value passed to it.

To download the source code for this article, you can visit our GitHub repository.

So, let’s start.

What Is Moq and Why Use It?

When we write tests for our code, the code often has dependencies on other objects. To isolate the code, we can use replacement mocked objects in place of the real dependencies. We could manually create mocks for all our dependencies by hand. However, it is often quicker and easier to use one of the many existing mocking frameworks for .NET.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Moq is one of the most popular examples of such a mocking framework.

Note: In August 2023, the original author of Moq added another of his projects, called SponsorLink, to version 4.20.0 of Moq. This was to encourage users to sponsor Moq. It was not received well by many contributors and users of Moq since SponsorLink (which at the time was also not open-source) collected email addresses from users and sent hashes of these emails to a cloud storage account. The author subsequently removed SponsorLink from later versions of Moq. However, he still seems committed to developing SponsorLink and it is unclear if it will be included again in the future. If you are already using Moq or choosing a mocking framework, it is worth reading this issue to fully understand the situation.

Return a Hard-Coded Value From a Mock Method

Let’s assume our code has a dependency on the Printer class, which takes an input string, communicates with an actual printer, and prints the text passed to it. It then returns the same text, which indicates printing was successful.

It wouldn’t make sense to include the real Printer class as part of our automated tests, since every time we run our tests, we would actually print test text. Not only would this likely slow down our tests, but it would also be a colossal waste of paper!

So let’s also assume the interface for the Printer class has a single method called Print():

public interface IPrinter
{
    string Print(string value);
}

We can then use Moq to create a mock of the real Printer class and return a hard-coded value when Print() is called:

var mockPrinter = new Mock<IPrinter>();
mockPrinter.Setup(iPrinter => iPrinter.Print(It.IsAny<string>())).Returns("Hello");

By calling the Setup() method on our mock, we can specify that whenever the Print() method is called with any input of type string to return “Hello”.

We can then use our mock within a test to return our test string. In order to call the Print() method on our mock, we first need to access the Object property on the mock which exposes the actual mocked object instance. We can then call Print() with our test input string and the mock returns "Hello":

IPrinter printer = mockPrinter.Object;
string result = printer.Print("Hello");

Return a Value of a Parameter From a Mock Method

A mock that returns a hard-coded value may be sufficient for our tests. However, our mock always returns “Hello”, regardless of the value of our test input string.

Perhaps our code which calls the Printer class is slightly more complex and we want to test the behavior of different calls to Printer with different inputs. Remember, we’re not testing the functionality of the Printer class (although other tests may cover it), instead, we’re testing the behavior of the code which calls the Printer dependency.

So let’s imagine the code calling Printer.Print() is actually a printer queue, responsible for calling the Printer dependency in a loop with different input strings. It has a PrintAll() method which returns the total number of characters successfully printed:

public class PrinterQueue
{    
    private readonly IPrinter _printer;    

    public PrinterQueue(IPrinter printer)    
    {        
        _printer = printer;    
    }    

    public int PrintAll(string[] jobs)    
    {        
        var characterCount = 0;        
        
        foreach (var job in jobs)        
        {            
            var result = _printer.Print(job);            
            characterCount += result.Length;        
        }        
        
        return characterCount;    
    }
}

To test the functionality of the PrinterQueue class, we mock the IPrinter dependency, but our tests will be more realistic when the mock Print() method returns the input string, rather than “Hello”. This would match the behavior of the actual Printer implementation.

Moq allows us to do this easily, since one of the Setup() method overloads takes a lambda expression. This lambda allows us to specify a function that will calculate the value to return.

In our case, we simply return the same input string:

var mockTranslator = new Mock<IPrinter>();
mockTranslator.Setup(iTranslator => iTranslator.Print(It.IsAny<string>()))
    .Returns((string input) => { return input; });

With our mock created, we can write a test for our PrinterQueue:

IPrinter printer = mockTranslator.Object;
var printerQueue = new PrinterQueue(printer);

var characterCountPrinted = printerQueue.PrintAll(new[] { "Hello", "Hola" });

Assert.AreEqual("HelloHola".Length, characterCountPrinted);

This allows us to verify that PrinterQueue does call Printer.Print() with both input strings. Had we used our simple mock then our test would fail, since the count returned would be incorrect.

We might even have a bug in the PrinterQueue class, where we call the Print() method twice, but we mistakenly pass the first string on both occasions:

for (var index = 0; index < jobs.Length; index++)
{
    var result = _printer.Print(jobs[0]); //bug
    characterCount += result.Length;
}

With our first simple mock, we wouldn’t have been able to detect this bug with our tests. We can though with a mock that returns the input value provided and a test with different length input strings.

Conclusion

In this article, we’ve seen why we might use Moq to mock the functionality of a dependent object when we write tests. Additionally, it can be useful to create a mock that can return a value based on an input parameter. We can achieve this by using a lambda expression with Moq.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!