Getting Started with Moq in C# (Generating Mock Objects)

目次

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 Moq to 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>() like Setup(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, use SetupAllProperties() 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 mock variable 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 the mock.Object property. 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.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次