Overview
“Moq” is a library used in unit testing to separate “external dependencies” such as databases or external APIs. This allows you to verify only the logic of the object you are testing. With Moq, you can easily create “fake objects (Mocks)” that implement an interface and freely define their behavior (Setup), such as what value to return when a method is called.
Specifications (Input/Output)
- Installation: Add the NuGet package
Moqto your project. - Input: The interface or abstract class you want to mock.
- Output: A Mock object that implements that type.
- Main Class:
Mock<T>
Package Installation
dotnet add package Moq --version 4.14.3
Basic Usage
using Moq;
// 1. Generate Mock object
// Create a fake object of the ICalculator interface
var mock = new Mock<ICalculator>();
// 2. Define behavior (Setup)
// Define a fake action: "If Add(1, 2) is called, return 100"
mock.Setup(c => c.Add(1, 2)).Returns(100);
// 3. Use the Mock object
// Get the actual implementation (the fake) via the .Object property
ICalculator calculator = mock.Object;
// The result will be 100
var result = calculator.Add(1, 2);
Full Code
This is an example of a console application that defines an interface and simulates its behavior using Moq.
using System;
using Moq;
namespace MoqSample
{
class Program
{
static void Main()
{
Console.WriteLine("--- Moq Basic Usage ---");
// 1. Generate Mock object
// Create a mock for the dependent interface (IMessageService)
var mockService = new Mock<IMessageService>();
// 2. Define method behavior (Setup)
// Configure GetMessage() to always return "Hello from Moq!"
mockService
.Setup(service => service.GetMessage())
.Returns("Hello from Moq!");
// 3. Pass the Mock object to the class under test
// mockService.Object acts as an implementation of IMessageService
var consumer = new MessageConsumer(mockService.Object);
// 4. Execution
// Internally, GetMessage() is called and returns the configured value
consumer.PrintMessage();
}
}
/// <summary>
/// The interface to be mocked
/// Usually represents parts that handle DB access or API communication
/// </summary>
public interface IMessageService
{
string GetMessage();
}
/// <summary>
/// The class under test
/// Designed to have IMessageService injected (DI) from the outside
/// </summary>
public class MessageConsumer
{
private readonly IMessageService _service;
public MessageConsumer(IMessageService service)
{
_service = service;
}
public void PrintMessage()
{
var message = _service.GetMessage();
Console.WriteLine($"Consumer received: {message}");
}
}
}
Customization Points
- Branching by Arguments: You can use
It.IsAny<T>()likeSetup(x => x.Method(It.IsAny<int>()))to match any argument. It is also possible to return different values only for specific arguments. - Setting Properties: You can mock property getters using
mock.SetupGet(x => x.Name).Returns("MockName"). Alternatively, useSetupAllProperties()to make the mock act as a stub that retains property values.
Points of Caution
- Interfaces Recommended: Moq works by dynamically generating proxy classes. Therefore, it primarily mocks interfaces or abstract classes. If you mock a regular class, the methods must be
virtual; otherwise, Moq cannot override them to change their behavior. - The Object Property: The
mockvariable itself is a management object used for configuration and verification. The “fake instance” that you pass to the class under test must be retrieved via themock.Objectproperty. Do not confuse the two.
Application
Verifying Invocations (Verify)
This feature allows you to check whether a method was actually called.
// Verify that GetMessage() was called exactly "once"
// If it was not called, the test fails (an exception occurs)
mockService.Verify(service => service.GetMessage(), Times.Once);
Summary
Using Moq starts with new Mock<T>(). This allows you to immediately create “convenient components” that return intended values without preparing real databases or Web APIs. This lets you focus entirely on verifying the logic of the class you are testing.
