如何使用 Moq.Dapper 模拟 QueryMultiple

2024-01-17

我正在编写单元测试用例,并且我成功地编写了单元测试用例Query。但我无法编写单元测试用例QueryMultiple.

对于查询我是这样写的:

 IEnumerable<ClientTestPurpose> fakeTestPurposes = new 
 List<ClientTestPurpose>()
 {
      new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name1"},
      new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name2"},
      new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name3"}
 };

 _mock.SetupDapper(x => x.Query<ClientTestPurpose>(It.IsAny<string>(), null, null, true, null, null)).Returns(fakeTestPurposes);

 var result = _libraryRepository.TestPurposes(clientModal.Id);

 Assert.IsNotNull(result);
 Assert.AreEqual(result.Count(), fakeTestPurposes.Count());   

如何写作QueryMultiple:

using (var multi = _db.QueryMultiple(spName, spParams, commandType: CommandType.StoredProcedure))
{
     var totals = multi.Read<dynamic>().FirstOrDefault();
     var aggregates = multi.Read<StatusModel>();
     var scripts = multi.Read<LibraryItemModel>();
     var runs = multi.Read<RunSummaryModel>();
     var filteredTotals = multi.Read<dynamic>().FirstOrDefault();
}

显然你使用 Moq.Dapper 扩展。这是代码SetupDapper and SetupDapperAsync method:

public static ISetup<IDbConnection, TResult> SetupDapper<TResult>(this Mock<IDbConnection> mock, Expression<Func<IDbConnection, TResult>> expression)
{
  MethodCallExpression body = expression.Body as MethodCallExpression;
  if ((body != null ? body.Method.DeclaringType : (Type) null) != typeof (SqlMapper))
    throw new ArgumentException("Not a Dapper method.");
  string name = body.Method.Name;
  if (name == "Execute")
    return (ISetup<IDbConnection, TResult>) DbConnectionInterfaceMockExtensions.SetupExecute(mock);
  if (name == "ExecuteScalar")
    return DbConnectionInterfaceMockExtensions.SetupExecuteScalar<TResult>(mock);
  if (name == "Query" || name == "QueryFirstOrDefault")
    return DbConnectionInterfaceMockExtensions.SetupQuery<TResult>(mock);
  throw new NotSupportedException();
}

public static ISetup<IDbConnection, Task<TResult>> SetupDapperAsync<TResult>(this Mock<IDbConnection> mock, Expression<Func<IDbConnection, Task<TResult>>> expression)
{
  MethodCallExpression body = expression.Body as MethodCallExpression;
  if ((body != null ? body.Method.DeclaringType : (Type) null) != typeof (SqlMapper))
    throw new ArgumentException("Not a Dapper method.");
  if (body.Method.Name == "QueryAsync")
    return DbConnectionInterfaceMockExtensions.SetupQueryAsync<TResult>(mock);
  throw new NotSupportedException();
}

正如你所看到的,Moq.Dapper 仅支持模拟Execute, ExecuteScalar, Query and QueryAsync方法。因此你可能会得到NotSupportedException试图嘲笑QueryMultiple。要模拟数据库行为,您可能需要首先引入另一个抽象级别,正如@TrueWill 在评论中所说。这只是一个关于您的情况的示例:

[Test]
public void DoSomethingWithQueryTest()
{
    // Arrange
    IEnumerable<ClientTestPurpose> fakeTestPurposes = new
        List<ClientTestPurpose>
        {
            new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name1" },
            new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name2" },
            new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name3" }
        };

    var mock = new Mock<ILibraryRepository>();
    mock.Setup(x => x.TestPurposes(It.IsAny<int>())).Returns(fakeTestPurposes);
    var logicService = new SomeLogicService(mock.Object);

    // Act
    var result = logicService.DoSomethingWithQuery(1);

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(result.Count(), fakeTestPurposes.Count());
}

[Test]
public void DoSomethingWithQueryMultipleTest()
{
    // Arrange
    SomeAggregate fakeTestPurposes = new SomeAggregate();

    var mock = new Mock<ILibraryRepository>();
    mock.Setup(x => x.TestQueryMultiple()).Returns(fakeTestPurposes);
    var logicService = new SomeLogicService(mock.Object);

    // Act
    var result = logicService.DoSomethingWithQueryMultiple();

    // Assert
    Assert.IsNotNull(result);
}

public interface ILibraryRepository
{
    IEnumerable<ClientTestPurpose> TestPurposes(int id);
    SomeAggregate TestQueryMultiple();
}

public class LibraryRepository : ILibraryRepository
{
    private readonly IDbConnection _db;

    public LibraryRepository(IDbConnection db)
    {
        _db = db ?? throw new ArgumentNullException(nameof(db));
    }

    public IEnumerable<ClientTestPurpose> TestPurposes(int id)
    {
        return _db.Query<ClientTestPurpose>("SQL here", new { id }, null, true, null, null);
    }

    public SomeAggregate TestQueryMultiple()
    {
        string spName = "SQL here";
        var spParams = new { Id = 1 };
        using (var multi = _db.QueryMultiple(spName, spParams, commandType: CommandType.StoredProcedure))
        {
            return new SomeAggregate
            {
                totals = multi.Read<dynamic>().FirstOrDefault(),
                aggregates = multi.Read<StatusModel>(),
                scripts = multi.Read<LibraryItemModel>(),
                runs = multi.Read<RunSummaryModel>(),
                filteredTotals = multi.Read<dynamic>().FirstOrDefault()
            };
        }
    }
}

public class SomeAggregate
{
    public IEnumerable<dynamic> totals { get; set; }
    public IEnumerable<StatusModel> aggregates { get; set; }
    public IEnumerable<LibraryItemModel> scripts { get; set; }
    public IEnumerable<RunSummaryModel> runs { get; set; }
    public IEnumerable<dynamic> filteredTotals { get; set; }
}

/// <summary>
/// Example logic server, that just returns results from repository
/// </summary>
public class SomeLogicService
{
    private readonly ILibraryRepository _repo;

    public SomeLogicService(ILibraryRepository repo)
    {
        _repo = repo;
    }

    public IEnumerable<ClientTestPurpose> DoSomethingWithQuery(int id)
    {
        return _repo.TestPurposes(id);
    }

    public SomeAggregate DoSomethingWithQueryMultiple()
    {
        return _repo.TestQueryMultiple();
    }
}

主要思想是将所有数据库特定的东西隐藏在后面ILibraryRepository并将需要测试的所有逻辑移动到某个逻辑服务器,该服务器将接收存储库作为依赖项。为了存储库中的代码应该简单、明显,包含所有数据库特定逻辑:连接、事务、命令、对象关系映射等。并且您不需要使用未测试来覆盖此代码。但是你确实涵盖了以下代码SomeLogicService使用单元测试,因为这是您真正需要测试的。您会看到 Dapper 扩展方法是相当低级的抽象,它不会隐藏使用数据库的细节,它们只是助手。希望能帮助到你。

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

如何使用 Moq.Dapper 模拟 QueryMultiple 的相关文章

  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • QUnit 删除依赖项上的方法会破坏针对该依赖项的测试

    在 Google Apps 脚本中 我正在对我正在开发的应用程序进行单元测试 使用 QUnit https github com simula innovation qunit tree gas gas 使用测试驱动开发 正在测试的代码 我
  • 指定自定义应用程序上下文

    我们正在将一些数据服务从使用 jersey spring 的 Jersey 1 x 迁移到使用 jersey spring3 的 Jersey 2 x 我们有一些继承自 JerseyTest 的测试类 其中一些类使用 web xml 文件中
  • 如何使用 NUnit(或者可能使用其他框架)测试异步方法?

    我有一个 ASP NET Web API 应用程序 带有一个具有异步方法的 ApiController 返回Task lt gt 对象并标有async关键词 public class MyApiController ApiControlle
  • 如何找到可能直接或间接调用给定方法的所有单元测试? (。网)

    如何找到可能直接或间接调用给定方法的所有单元测试 当我改变方法时 我希望知道要运行的最佳测试 必须有一个工具可以做到这一点 由于我们有很多接口 所以我对所有在实现接口的类上至少有一个路径 var 植入方法时调用接口上的方法的单元测试感兴趣
  • 无法在单元测试中检查响应标头

    我有一个 Http 处理程序的单元测试 在其中我创建了一个HttpResponse对象并将其传递给我的 Http 处理程序的方法之一 我的一项测试尝试验证响应标头是否已正确设置 Assert AreEqual gzip response H
  • Python3模拟用另一个函数替换函数

    如何使用 python 中的另一个函数来模拟一个函数 该函数也将提供一个模拟对象 我有类似以下操作的代码 def foo arg1 arg2 r bar arg1 does interesting things 我想替换的实现bar函数 让
  • 我尝试使用 googlemock 模拟简单的 C++ 方法有什么问题?

    As per 用于对进行标准库调用的 C 方法进行单元测试的模式 https stackoverflow com questions 5779618 patterns for unit testing a c method that mak
  • 为什么调用fail()会使用JUnit在Java类中进行编译

    这似乎不应该编译和运行Object没有fail 方法 在编译时发生了一些奇怪的事情吗 我正在使用 NetBeans import static org junit Assert import org junit Test public cl
  • 尚未注册类型“Microsoft.AspNetCore.Mvc...”的服务

    我正在尝试测试此控制器方法 以确保它重定向到另一个控制器方法或存在模型错误 public IActionResult ResetPassword ResetPasswordViewModel viewModel if viewModel N
  • 不返回值的方法的起订量调用库(void 方法)

    我正在尝试模拟正在测试的类 以便在测试它们时可以对各个方法进行调用 这将允许我仅将方法设置测试为调用库 并且从测试方法中调用的所有其他方法 同一类 都将被模拟 但是 对于不返回值的方法 我无法执行此操作 对于不返回值的方法 智能感知只是不显
  • Ruby on Rails 中 RESTful POST 的功能测试

    我想为我正在 Ruby on Rails 应用程序中开发的 RESTful Web 服务编写功能测试 该测试是 POST 请求 其中请求正文是纯 XML 文档而不是表单 有关如何执行此操作的任何指示 我遇到的问题是如何在调用 post 方法
  • API 的集成与单元测试

    我们可以考虑向端点 单元或集成测试 发送请求吗 import lib from testing lib const testClient expect lib const response testClient request app ge
  • 测试框架允许测试依赖于其他测试

    我想知道是否有一个测试框架允许将测试声明为依赖于其他测试 这意味着如果它们所依赖的测试未通过 则不应运行它们 或者不应突出显示它们的结果 这种设置的目的是在存在许多测试失败的情况下更容易确定根本原因 作为奖励 如果有某种方法可以使用一个测试
  • Grails Spock 单元测试需要模拟事务管理器

    在 Grails 3 1 12 中 我想对服务进行单元测试 Transactional class PlanService List
  • 使用 NSURLSession 进行单元测试

    我想为使用共享的方法编写单元测试NSURLSession 特别是 NSURLSessionDataTask下载数据 基本上 我希望目标方法能够接收模拟响应 数据 而不需要互联网连接 模拟这些组件的不太不显眼的方式是什么 我正在考虑填充NSU
  • Python 单元测试 Google Bigquery

    我在对以下代码块进行单元测试时遇到问题 from google cloud import bigquery from google oauth2 import service account def run query query gcp
  • 如何模拟类路径上属性文件的存在?

    这肯定是一个常见问题 我有一个像这样的属性文件my settings properties由应用程序类读取 当我编写测试类时 它需要测试可能存在的不同场景my settings properties为了确保最大的代码覆盖率 例如空属性文件
  • 构造函数上的分支未涵盖

    我正在使用 Jasmine 创建单元测试 我对所涵盖的分支有疑问 有谁知道为什么代码部分显示分支没有被覆盖 如下所示 这是单元测试 describe MyComponent gt let component MyComponent let

随机推荐

  • Python 习语与多次调用 os.path.dirname 获得相同的结果?

    我发现自己需要在源树中获取 python 文件的父目录 该源树是具有一定规律性的多个目录 必须多次调用 dirname 很笨拙 我环顾四周 很惊讶没有找到关于此的帖子 一般场景是 import os path as op third deg
  • 如何在 MSVC 下检测 C++11 的 noexcept 功能?

    我正在使用 C 库 该库的最低要求是 C 03 我在 Visual Studio 2015 下收到一些关于抛出析构函数的警告 algparam h 271 warning C4297 AlgorithmParametersBase Algo
  • 前端和后端可以共享同一个package.json吗?

    我有一个小型个人项目 正在一个存储库中开发 后端是 Node js 服务器 前端是 Vue js 应用程序 我希望它们共享相同的 package json 我想这样做的唯一原因是因为我想使用 scripts 一个通用的 package js
  • 如何解决松散耦合/依赖注入和富域模型之间的冲突?

    Edit 这不是理论层面的冲突 而是实施层面的冲突 另一个编辑 问题在于域模型不作为纯数据 DTO 而不是更丰富 更复杂的对象映射 其中 Order 具有 OrderItems 和一些calculateTotal 逻辑 具体问题是 例如 该
  • 在下次调用之前中断 spring 调度程序任务

    我有一个 Spring Boot 应用程序 它将成为我们想要触发的其他几个进程的编排服务 我目前使用 Spring Scheduling 从数据库动态提取 cron 来设置它 我引入了一个休息方法来触发从数据库中提取新的 cron 信息的过
  • 在 c++11 中全局修复种子

    我正在尝试使用新的c
  • 如何捕获和查看 Cortex-M4 MCU 上的 ITM 跟踪信息?

    我想捕获 解码和查看 Cortex M4 MCU 在我的例子中是 Atmel SAM4S 的 ITM 跟踪信息 特别是 我想捕获与板上其他信号相关的异常和用户跟踪数据 即在同一时间线上显示所有信号和跟踪信息 这可以通过以下步骤完成 将调试器
  • AngularJS 指令绑定具有多个参数的函数

    我在将控制器中定义的函数与指令中的回调函数绑定时遇到一些问题 我的代码如下所示 在我的控制器中 scope handleDrop function elementId file console log handleDrop called 然
  • 在sql server中对加密列建立索引

    我将患者健康信息存储在 SQL Server 2012 数据库中 当我搜索病人的姓名时 他们的名字是加密的 所以搜索速度非常慢 如何在加密列上添加索引 我在 varbinary 字段上使用对称密钥加密 256 位 AES 患者的名字 姓氏
  • Maven 版本控制最佳实践 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 更改 Maven 项目版本 发布此版本然后返回到的最佳方法是什么 SNAPSHOT发展 目前我正在做以下事情 检索当前版本 最有可能的是SNAP
  • 如何绘制多列的条形图 3D 投影

    我有一个表 其中包含根据两个不同参数的三个不同时间特征 我想在 x 轴和 y 轴上绘制这些参数 并在 z 轴上显示三个不同时间的条形 我创建了一个简单的条形图 其中绘制了其中一个时间特征 import numpy as np import
  • 是否可以将数据从 DelegatingHandler 传递到 ASP.NET Web API 中的控制器?

    我正在实现一个与授权相关的 DelegatingHandler 其中我从数据库加载 api 用户 调用者 配置文件 当授权成功时 我想将此实例传递给控制器 否则我必须再次加载它 有没有办法在不使用会话或依赖存储库缓存的情况下执行此操作 Ht
  • 当网格被过滤时,Kendo 工具栏 AddNew 按钮不起作用

    我有一个小的剑道网格 设置如下 以一种令人难以置信的神秘方式 添加新 的控制器操作 即BatchCreate仅当您在单击 添加新项 后单击另一个命令按钮时才会调用 例如 a 单击 添加新的 什么也没有发生 b 重新加载页面 点击 Add N
  • 了解第 3 方 iframe 安全性?

    Facebook 和其他公司提供了一些小的 iframe 片段 我可以将它们放入我的网站中 例子 我想知道的是 如果我把这段代码放在我这边 他们加载到我页面中的代码可以访问我页面的 DOM 吗 如果是的话 我看到一些安全问题 同样 Face
  • 在 Haskell 中模拟路径依赖类型

    这是我想做的事情的一个简化示例 假设你有一个HList对 let hlist HCons 1 1 HCons 0 2 HCons 0 1 5 HNil 现在我想写一个函数replaceAll它将用相同类型的第一个 值 替换给定类型的所有 键
  • 随机选择ArangoDB中的一个文档

    有没有办法使用 AQL 从集合中随机返回文档 我想创建一个随机图用于测试目的 我还没有弄清楚如何从集合中随机选择文档 我希望我能够做这样的事情 db query RETURN nodes RAND 0 LENGTH nodes toArra
  • 在 React Native 中如何更改 Android 上的根视图背景颜色?

    我在网上读过一些教程 但大部分都是关于 iOS 的 或者一些关于 Android 的 但是使用旧版本的 React 现在一切都变了 如果我打开 MainActivity java 只有一种方法 Override protected Stri
  • 使用 LDAP Active Directory 身份验证的 ActiveMQ Web 控制台

    努力让 ActiveMQ Web 控制台使用 LDAP 并根据 Active Directory 进行身份验证 启动 MQ 时没有错误 出现用户名 密码登录框提示 但在插入正确的凭据时没有进展 Version 5 15 6 登录配置 amq
  • 为什么 C++ 不需要“new”语句来初始化 std::vector?

    考虑 bar h class bar Standard stuff omitted std vector
  • 如何使用 Moq.Dapper 模拟 QueryMultiple

    我正在编写单元测试用例 并且我成功地编写了单元测试用例Query 但我无法编写单元测试用例QueryMultiple 对于查询我是这样写的 IEnumerable