如何在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
相关产品推荐
相关产品推荐

