You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#单元测试中Mock IProcess(基于Autofac和AutoMock)

解决方案

首先明确两种场景,分别给出对应的Mock实现方式:

场景1:GetClientIProcess是依赖类的方法

假设该方法属于一个服务接口IProcessService,你的测试类依赖这个接口获取IProcess实例:

第一步:定义接口与实现类

public interface IProcessService
{
    System.Diagnostics.Abstractions.IProcess GetClientIProcess(int ProcessId);
}

public class ProcessService : IProcessService
{
    public System.Diagnostics.Abstractions.IProcess GetClientIProcess(int ProcessId)
    {
        var temp = Process.GetProcessById(ProcessId);
        return new System.Diagnostics.Abstractions.Process(temp);
    }
}

第二步:编写单元测试

using Autofac.Extras.AutoMock;
using Moq;
using Xunit;

public class MyBusinessClassTests
{
    [Fact]
    public void TargetMethod_UsesMockedIProcess_Correctly()
    {
        // 1. 初始化AutoMock容器
        using var mockContainer = AutoMock.GetLoose();

        // 2. 创建Mock的IProcess实例,按需设置属性
        var mockedProcess = new Mock<System.Diagnostics.Abstractions.IProcess>();
        mockedProcess.Setup(p => p.Id).Returns(1234); // 模拟进程ID

        // 3. 配置依赖服务的Mock行为
        mockContainer.Mock<IProcessService>()
            .Setup(s => s.GetClientIProcess(It.IsAny<int>())) // 可指定特定ProcessId,如It.Is<int>(id => id == 1234)
            .Returns(mockedProcess.Object);

        // 4. 创建被测试类实例,AutoMock自动注入依赖
        var sut = mockContainer.Create<MyBusinessClass>();

        // 5. 执行被测试方法
        sut.TargetTestMethod(1234);

        // 6. 验证调用行为(可选)
        mockContainer.Mock<IProcessService>()
            .Verify(s => s.GetClientIProcess(1234), Times.Once);
    }
}

场景2:GetClientIProcess是被测试类自身的方法

如果该方法属于被测试类,需要先将其改为虚方法才能被Moq拦截:

第一步:修改被测试类

public class MyBusinessClass
{
    // 改为虚方法以支持Mock
    public virtual System.Diagnostics.Abstractions.IProcess GetClientIProcess(int ProcessId)
    {
        var temp = Process.GetProcessById(ProcessId);
        return new System.Diagnostics.Abstractions.Process(temp);
    }

    // 被测试的业务方法
    public string GetProcessInfo(int processId)
    {
        var process = GetClientIProcess(processId);
        return $"Process ID: {process.Id}";
    }
}

第二步:编写单元测试

using Autofac.Extras.AutoMock;
using Moq;
using Xunit;

public class MyBusinessClassTests
{
    [Fact]
    public void GetProcessInfo_ReturnsMockedProcessId()
    {
        using var mockContainer = AutoMock.GetLoose();

        // 1. 创建Mock的IProcess实例
        var mockedProcess = new Mock<System.Diagnostics.Abstractions.IProcess>();
        mockedProcess.Setup(p => p.Id).Returns(5678);

        // 2. 创建被测试类的实例并Mock其虚方法
        var sut = mockContainer.Create<MyBusinessClass>();
        Mock.Get(sut)
            .Setup(s => s.GetClientIProcess(It.IsAny<int>()))
            .Returns(mockedProcess.Object);

        // 3. 执行测试并断言结果
        var result = sut.GetProcessInfo(5678);
        Assert.Equal("Process ID: 5678", result);

        // 4. 验证方法调用(可选)
        Mock.Get(sut)
            .Verify(s => s.GetClientIProcess(5678), Times.Once);
    }
}

关键注意事项

  • 确保已安装System.Diagnostics.AbstractionsNuGet包,它提供了可Mock的进程抽象接口
  • 依赖类场景下,必须面向接口而非具体类编程,否则无法通过AutoMock替换实现
  • 被测试类自身方法的场景下,方法必须标记为virtual,否则Moq无法拦截并替换返回值

内容的提问来源于stack exchange,提问作者KingGizzard237

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:52:35