使用 Moq 模拟惰性接口

2023-11-26

我想要模拟惰性接口,但我得到了object reference not set to an instance of an object例外。

‌这是正在测试的类:

public class ProductServiceService : IProductServiceService
{
    private readonly Lazy<IProductServiceRepository> _productServiceRepository;
    private readonly Lazy<IProductPackageRepository> _productPackageRepository;

    public ProductServiceService(
        Lazy<IProductServiceRepository> productServiceRepository,
        Lazy<IProductPackageRepository> productPackageRepository)
    {
        _productServiceRepository = productServiceRepository;
        _productPackageRepository = productPackageRepository;
    }

    public async Task<OperationResult> ValidateServiceAsync(ProductServiceEntity service)
    {
        var errors = new List<ValidationResult>();

        if (!await _productPackageRepository.Value.AnyAsync(p => p.Id == service.PackageId))
            errors.Add(new ValidationResult(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));
       .
       .
       .
        return errors.Any()
            ? OperationResult.Failed(errors.ToArray())
            : OperationResult.Success();
    }
}

这是测试课

[Fact, Trait("Category", "Product")]
public async Task Create_Service_With_Null_Financial_ContactPerson_Should_Fail()
{
    // Arrange
    var entity = ObjectFactory.Service.CreateService(packageId: 1);

    var mockProductServiceRepository = new Mock<Lazy<IProductServiceRepository>>();

    var repo = new Mock<IProductPackageRepository>();
    repo.Setup(r => r.AnyAsync(It.IsAny<Expression<Func<ProductPackageEntity, bool>>>()));
    var mockProductPackageRepository = new Lazy<IProductPackageRepository>(() => repo.Object);

    var sut = new ProductServiceService(mockProductServiceRepository.Object, mockProductPackageRepository);

    // Act
    var result = await sut.AddServiceAsync(service);

    // Assert
    Assert.False(result.Succeeded);
    Assert.Contains(result.ErrorMessages, error => error.Contains(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));
}

mockProductPackageRepository始终为空。我关注了这篇博文,但仍然遇到空引用异常。

如何使用 Moq 在 C# 单元测试中模拟对象的延迟初始化

Update: here is a screen that indicates fakeProductPackageRepository is null. enter image description here enter image description here


这是您的示例的重构版本:

[Fact, Trait("Category", "Product")]
public async Task Create_Service_With_Null_Financial_ContactPerson_Should_Fail() {
    // Arrange
    var entity = ObjectFactory.Service.CreateService(packageId = 1);

    var productServiceRepositoryMock = new Mock<IProductServiceRepository>();

    var productPackageRepositoryMock = new Mock<IProductPackageRepository>();
    productPackageRepositoryMock
        .Setup(repository => repository.AnyAsync(It.IsAny<Expression<Func<ProductPackageEntity, bool>>>()))
        .ReturnsAsync(false);

    //Make use of the Lazy<T>(Func<T>()) constructor to return the mock instances
    var lazyProductPackageRepository = new Lazy<IProductPackageRepository>(() => productPackageRepositoryMock.Object);
    var lazyProductServiceRepository = new Lazy<IProductServiceRepository>(() => productServiceRepositoryMock.Object);

    var sut = new ProductServiceService(lazyProductServiceRepository, lazyProductPackageRepository);

    // Act
    var result = await sut.AddServiceAsync(service);

    // Assert
    Assert.False(result.Succeeded);
    Assert.Contains(result.ErrorMessages, error => error.Contains(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));
}

UPDATE

下列最小、完整且可验证的示例您所陈述的问题经测试后通过。

[TestClass]
public class MockLazyOfTWithMoqTest {
    [TestMethod]
    public async Task Method_Under_Test_Should_Return_True() {
        // Arrange
        var productServiceRepositoryMock = new Mock<IProductServiceRepository>();

        var productPackageRepositoryMock = new Mock<IProductPackageRepository>();
        productPackageRepositoryMock
            .Setup(repository => repository.AnyAsync())
            .ReturnsAsync(false);

        //Make use of the Lazy<T>(Func<T>()) constructor to return the mock instances
        var lazyProductPackageRepository = new Lazy<IProductPackageRepository>(() => productPackageRepositoryMock.Object);
        var lazyProductServiceRepository = new Lazy<IProductServiceRepository>(() => productServiceRepositoryMock.Object);

        var sut = new ProductServiceService(lazyProductServiceRepository, lazyProductPackageRepository);

        // Act
        var result = await sut.MethodUnderTest();

        // Assert
        Assert.IsTrue(result);
    }

    public interface IProductServiceService { }
    public interface IProductServiceRepository { }
    public interface IProductPackageRepository { Task<bool> AnyAsync();}

    public class ProductServiceService : IProductServiceService {
        private readonly Lazy<IProductServiceRepository> _repository;
        private readonly Lazy<IProductPackageRepository> _productPackageRepository;

        public ProductServiceService(
            Lazy<IProductServiceRepository> repository,
            Lazy<IProductPackageRepository> productPackageRepository) {
            _repository = repository;
            _productPackageRepository = productPackageRepository;
        }

        public async Task<bool> MethodUnderTest() {
            var errors = new List<ValidationResult>();

            if (!await _productPackageRepository.Value.AnyAsync())
                errors.Add(new ValidationResult("error"));

            return errors.Any();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Moq 模拟惰性接口 的相关文章

  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • Spock模拟inputStream导致无限循环

    我有一个代码 gridFSFile inputStream bytes 当我尝试这样测试时 given def inputStream Mock InputStream def gridFSDBFile Mock GridFSDBFile
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反

随机推荐