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

.NET Core 8 MSTest中System.Fakes使用问题及静态方法Mock替代方案

.NET Core 8 MSTest项目中使用System.Fakes的解决方案及静态方法Mock替代方案

关于System.Fakes的问题说明

微软官方的Fakes(包含Shims与Stubs)是仅针对.NET Framework设计的测试工具,.NET Core/.NET 8项目不支持Visual Studio中的“Add Fakes”可视化操作,也无法自动生成System.Fakes这类Shim命名空间。你引用的Microsoft.QualityTools.Testing.Fakes包在.NET Core环境下无法正常工作,这就是代码中出现“System命名空间中不存在Fakes”错误的根本原因。

可行解决方案及替代方案

方案1:使用社区维护的Fakes.Net包

这是针对.NET Core/.NET 5+的Fakes替代实现,支持生成Shim与Stub类型,用法和官方Fakes一致:

  1. 安装NuGet包:
    Install-Package Fakes.Net
    
  2. 在测试项目根目录创建System.fakes配置文件,内容如下:
    <Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
      <Assembly Name="System" Version="8.0.0.0"/>
    </Fakes>
    
  3. 编译测试项目后,会自动生成System.Fakes命名空间,即可按原逻辑编写测试:
    using Microsoft.QualityTools.Testing.Fakes;
    using System.Fakes;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    [TestClass]
    public class DateTimeTests
    {
        [TestMethod]
        public void MockDateTimeNow()
        {
            using (ShimsContext.Create())
            {
                ShimDateTime.NowGet = () => new DateTime(1837, 1, 1);
                var currentYear = DateTime.Now.Year;
                Assert.AreEqual(1837, currentYear);
            }
        }
    }
    

方案2:封装静态方法+依赖注入(推荐)

通过封装静态方法为接口,结合依赖注入实现可测试性,兼容所有主流Mock框架(如Moq):

  1. 封装静态方法为接口与实现类:
    // 定义接口
    public interface IDateTimeProvider
    {
        DateTime Now { get; }
    }
    
    // 生产环境实现
    public class DefaultDateTimeProvider : IDateTimeProvider
    {
        public DateTime Now => DateTime.Now;
    }
    
  2. 业务类中注入该接口,替代直接调用静态方法:
    public class BusinessService
    {
        private readonly IDateTimeProvider _dateTimeProvider;
    
        public BusinessService(IDateTimeProvider dateTimeProvider)
        {
            _dateTimeProvider = dateTimeProvider;
        }
    
        public int GetCurrentYear()
        {
            return _dateTimeProvider.Now.Year;
        }
    }
    
  3. 测试时用Moq Mock接口:
    using Moq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    [TestClass]
    public class BusinessServiceTests
    {
        [TestMethod]
        public void GetCurrentYear_ReturnsMockedYear()
        {
            // 准备Mock对象
            var mockProvider = new Mock<IDateTimeProvider>();
            mockProvider.Setup(p => p.Now).Returns(new DateTime(1837, 1, 1));
            var service = new BusinessService(mockProvider.Object);
    
            // 执行测试
            var result = service.GetCurrentYear();
    
            // 断言结果
            Assert.AreEqual(1837, result);
        }
    }
    
    该方案符合依赖倒置原则,代码可维护性更强,是长期项目的推荐方案。

方案3:使用支持静态Mock的第三方框架

部分第三方Mock框架支持直接Mock静态方法,以下以Moq的扩展包为例:

  1. 安装NuGet包:
    Install-Package Moq.Contrib.MockStatic
    
  2. 编写测试代码:
    using Moq;
    using Moq.Contrib.MockStatic;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    [TestClass]
    public static class StaticMethodMockTests
    {
        [TestMethod]
        public void MockDateTimeNowDirectly()
        {
            using (MockStatic<DateTime> mock = new MockStatic<DateTime>())
            {
                mock.Setup(x => x.Now).Returns(new DateTime(1837, 1, 1));
                var result = DateTime.Now.Year;
                Assert.AreEqual(1837, result);
            }
        }
    }
    
    注意:这类方案通过IL注入实现,可能存在性能开销,部分场景下兼容性需验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:25:14