我如何模拟 FromSql() 方法?

2023-11-26

我想知道除了构建一个包装器来嘲笑之外还有什么方法吗FromSql?我知道这个方法是静态的,但是因为他们添加了类似的东西AddEntityFrameworkInMemoryDatabase对于实体框架核心,我认为也可能有一个解决方案,我在我的项目中使用 EF Core 1.0.1。

我的最终目标是测试这个方法:

public List<Models.ClosestLocation> Handle(ClosestLocationsQuery message)
{
    return _context.ClosestLocations.FromSql(
        "EXEC GetClosestLocations {0}, {1}, {2}, {3}",
        message.LocationQuery.Latitude,
        message.LocationQuery.Longitude,
        message.LocationQuery.MaxRecordsToReturn ?? 10,
        message.LocationQuery.Distance ?? 10
    ).ToList();
}

我想确保我的查询是使用我传递给它的相同对象进行处理的,基于这个答案在实体框架 6 中我可以这样做:

[Fact]
public void HandleInvokesGetClosestLocationsWithCorrectData()
{
    var message = new ClosestLocationsQuery
    {
        LocationQuery =
            new LocationQuery {Distance = 1, Latitude = 1.165, Longitude = 1.546, MaxRecordsToReturn = 1}
    };

    var dbSetMock = new Mock<DbSet<Models.ClosestLocation>>();

    dbSetMock.Setup(m => m.FromSql(It.IsAny<string>(), message))
        .Returns(It.IsAny<IQueryable<Models.ClosestLocation>>());

    var contextMock = new Mock<AllReadyContext>();

    contextMock.Setup(c => c.Set<Models.ClosestLocation>()).Returns(dbSetMock.Object);

    var sut = new ClosestLocationsQueryHandler(contextMock.Object);
    var results = sut.Handle(message);

    contextMock.Verify(x => x.ClosestLocations.FromSql(It.IsAny<string>(), It.Is<ClosestLocationsQuery>(y =>
        y.LocationQuery.Distance == message.LocationQuery.Distance &&
        y.LocationQuery.Latitude == message.LocationQuery.Latitude &&
        y.LocationQuery.Longitude == message.LocationQuery.Longitude &&
        y.LocationQuery.MaxRecordsToReturn == message.LocationQuery.MaxRecordsToReturn)));
}

但不同于SqlQuery<T>在 EF 6 中,FromSql<T>在 EF Core 中是静态扩展方法,我问这个问题是因为我认为我可能从错误的角度处理这个问题,或者可能有比包装器更好的替代方案,我很感激对此的任何想法。


我也遇到了同样的情况,菲利普给出的答案有帮助,但主要方法是扔System.ArgumentNullException.

From 这个链接,我终于能够编写一些单元测试了......

这是我正在测试的课程:

public class HolidayDataAccess : IHolidayDataAccess
{
    private readonly IHolidayDataContext holDataContext;

    public HolidayDataAccess(IHolidayDataContext holDataContext)
    {
        this.holDataContext = holDataContext;
    }

    public async Task<IEnumerable<HolidayDate>> GetHolidayDates(DateTime startDate, DateTime endDate)
    {
        using (this.holDataContext)
        {
            IList<HolidayDate> dates = await holDataContext.Dates.FromSql($"[dba].[usp_GetHolidayDates] @StartDate = {startDate}, @EndDate = {endDate}").AsNoTracking().ToListAsync();
            return dates;
        }
    }
}

这是测试方法:

[TestMethod]
public async Task GetHolidayDates_Should_Only_Return_The_Dates_Within_Given_Range()
{
    // Arrange.

        SpAsyncEnumerableQueryable<HolidayDate> dates = new SpAsyncEnumerableQueryable<HolidayDate>();
        dates.Add(new HolidayDate() { Date = new DateTime(2018, 05, 01) });
        dates.Add(new HolidayDate() { Date = new DateTime(2018, 07, 01) });
        dates.Add(new HolidayDate() { Date = new DateTime(2018, 04, 01) });
        dates.Add(new HolidayDate() { Date = new DateTime(2019, 03, 01) });
        dates.Add(new HolidayDate() { Date = new DateTime(2019, 02, 15) });


    var options = new DbContextOptionsBuilder<HolidayDataContext>()
        .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
        .Options;

    HolidayDataContext context = new HolidayDataContext(options);

    context.Dates = context.Dates.MockFromSql(dates);

    HolidayDataAccess dataAccess = new HolidayDataAccess(context);

    //Act.
    IEnumerable<HolidayDate> resutlDates = await dataAccess.GetHolidayDates(new DateTime(2018, 01, 01), new DateTime(2018, 05, 31));

    // Assert.

    Assert.AreEqual(resutlDates.Any(d => d.Date != new DateTime(2019, 03, 01)), true);
    Assert.AreEqual(resutlDates.Any(d => d.Date != new DateTime(2019, 02, 15)), true);

    // we do not need to call this becuase we are using a using block for the context...
    //context.Database.EnsureDeleted();
}

To use UseInMemoryDatabase你需要添加Microsoft.EntityFrameworkCore.InMemory包裹来自NuGet辅助类在这里:

public class SpAsyncEnumerableQueryable<T> : IAsyncEnumerable<T>, IQueryable<T>
{
    private readonly IList<T> listOfSpReocrds;

    public Type ElementType => throw new NotImplementedException();

    public IQueryProvider Provider => new Mock<IQueryProvider>().Object;

    Expression IQueryable.Expression => throw new NotImplementedException();

    public SpAsyncEnumerableQueryable()
    {
        this.listOfSpReocrds = new List<T>();
    }        

    public void Add(T spItem) // this is new method added to allow xxx.Add(new T) style of adding sp records...
    {
        this.listOfSpReocrds.Add(spItem);
    }

    public IEnumerator<T> GetEnumerator()
    {
       return this.listOfSpReocrds.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    IAsyncEnumerator<T> IAsyncEnumerable<T>.GetEnumerator()
    {
        return listOfSpReocrds.ToAsyncEnumerable().GetEnumerator();
    }
}

...以及包含 FromSql 方法模拟的 Db 扩展类。

public static class DbSetExtensions
{
    public static DbSet<T> MockFromSql<T>(this DbSet<T> dbSet, SpAsyncEnumerableQueryable<T> spItems) where T : class
    {
        var queryProviderMock = new Mock<IQueryProvider>();
        queryProviderMock.Setup(p => p.CreateQuery<T>(It.IsAny<MethodCallExpression>()))
            .Returns<MethodCallExpression>(x => spItems);

        var dbSetMock = new Mock<DbSet<T>>();
        dbSetMock.As<IQueryable<T>>()
            .SetupGet(q => q.Provider)
            .Returns(() => queryProviderMock.Object);

        dbSetMock.As<IQueryable<T>>()
            .Setup(q => q.Expression)
            .Returns(Expression.Constant(dbSetMock.Object));
        return dbSetMock.Object;
    }
}

希望这可以帮助!

Edits:重构 SpAsyncEnumerableQueryable 类以具有 Add 方法。摆脱了需要 T 数组的参数化构造。已实现IQueryProvider Provider => new Mock<IQueryProvider>().Object;支持.AsNoTracking()。异步调用 ToList。

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

我如何模拟 FromSql() 方法? 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 工作流程系统中的单元/自动化测试

    您是否对像 K2 这样的复杂工作流程系统进行自动化测试 我们正在构建一个在 Sharepoint 2007 和 K2 之间进行广泛集成的系统 我什至无法想象从哪里开始自动化测试 因为工作流程涉及多个用户与 Sharepoint K2 工作流
  • 重载<<的返回值

    include
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定

随机推荐

  • 转义 LDAP 查询字符串中的非特殊字符

    我希望我已经恰当地命名了这个问题 这里的主题有点复杂 我创建了一个函数C 创建 Active Directory 用户 使用需要如下所示的 LDAP 字符串 userinfo displayName Surname Firstname CN
  • 从流 onError 中恢复的惯用方法

    免责声明 这是上一篇的延续2 个相关流的安全更新问题 是什么惯用语处理 RxJS 或任何其他 RX 实现 中允许流不终止的错误的方法 相关代码是 function convert unit value var request request
  • TCP P2P 无需服务器

    是否可以编写没有服务器的TCP P2P程序 当我在谷歌上搜索这个问题时 我发现了一些关于 NAT 穿越 UPnP 的内容 我可以以某种方式使用它们吗 是的 你可以 正如 GrandmasterB 指出的那样 每个对等点都有服务器和客户端套接
  • 使用 XAML 声明 Nullable int (int?)

    我正在尝试将组合框绑定到 ViewModel 上的属性 目标类型是short 我想要null是一个选择 基本上我希望组合框中第一项的值是 x Null
  • 在 Angular 2 中输出组件数组

    我正在 Angular 2 和 TypeScript 中构建一个模式组件 该组件将具有不同的视图 页面 它不会有选项卡 但概念非常相似 基本上我正在努力寻找一种方法来做到这一点 在我的模式组件中 我想输出不同的视图 页面 每个组件本身都应该
  • Phonegap - Android 如何在软键盘可见时调整全屏模式下的布局

    我正在为三星 Galaxy Tab 3 开发一个phonegap应用程序 当该应用程序处于全屏模式时 软键盘会隐藏文本输入字段 并且无法滚动页面来查看内容 我该如何解决这个问题 在花了一天时间尝试了该网站上几乎所有可能的解决方案后 没有任何
  • ExceptionContext.ExceptionHandled 更改为 true。异常在哪里处理?

    我正在使用全局操作过滤器来处理和记录所有异常 public static void RegisterGlobalFilters GlobalFilterCollection filters filters Add new ElmahHand
  • 在 ScrollView 中将文本对齐为前导 - SWIFTUI

    我有一个ScrollView ScrollView VStack alignment leading Text userData username userData age fontWeight semibold font Font sys
  • 安全处理 org.xml.sax.SAXNotRecognizedException 导致 Tomcat 内运行 java.lang.IllegalStateException 的解决方案

    我在接收 Xml 并尝试解析它时遇到此异常 负责此操作的代码在作为独立应用程序运行时经过了良好的测试 不过我现在正在将它集成到 Tomcat 中 堆栈跟踪是 java lang IllegalStateException org xml s
  • 如何使用 Python 和 matplotlib 绘制 4D 绘图

    我正在寻找一种使用 Python 和 matplotlib 创建四维图 曲面加色标 的方法 我能够使用前三个变量生成曲面 但我没有成功添加第四个变量的色标 下面是我的数据的一小部分 任何帮助将不胜感激 谢谢 数据子集 var1 var2 v
  • OpenCV 从字节数组创建 Mat

    在我的 C dll 中 我从字节数组创建 Mat BYTE ptrImageData Image data is in this array passed to this function Mat newImg Mat nImageHeig
  • 如何绑定命令以双击 DataGrid 中的行

    我开发了一个 WPF UserControl 旨在用作选择列表 如下所示 绑定到实体 例如员工 的 CollectionView 的 DataGrid DataGrid 上方的文本框 可用于过滤 DataGrid 中显示的项目 我想公开一个
  • Spark 数据集过滤器性能

    我一直在尝试不同的方法来过滤类型数据集 事实证明 性能可能会有很大不同 该数据集是基于 1 6 GB 行 33 列 4226047 行的数据创建的 DataSet 通过加载 csv 数据创建并映射到案例类 val df spark read
  • cakephp 查找列表

    您好 我希望能够使用 find 生成一个列表 以便我可以在选择帮助器中使用 但有一个问题 我也想获取 id 名称 第一个 最后一个 那么我怎样才能实现它呢 我希望将first name和last name作为name加入 我怎样才能实现它
  • AVD 的 SD 卡大小的合理值是多少? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我发现当我设置 AVD 时 并不真正知道我在做什么 只是按照在线教程或其他内容进行操作 我给 SD 卡的值是 100 MiB 这样的设置合理吗 我应该改用 8 GiB 之类的东西吗 还是这
  • 用于打开 URL 的 Google Apps 脚本

    有没有办法编写谷歌应用程序脚本 以便在运行时 第二个浏览器窗口打开 www google com 或我选择的另一个网站 我试图在这里想出一个解决我之前问题的方法 我可以在 Google Apps 电子表格的消息框中添加超链接吗 该函数打开一
  • jQuery 表单验证 - 错误标签的 CSS

    我使用与 jquery 网站上使用的完全相同的示例进行简单的表单验证 http docs jquery com Plugins Validation 但有一件事我不明白 示例中的错误消息显示在每个输入字段的右侧 我想在每个输入字段下显示错误
  • iOS 项目将 Xcode 4.2 更新到 Xcode 4.5

    在我的项目中 我已经使用 XCode 4 2 完成了 90 的开发 只需要支持 4 x 5 x 现在我还需要为 iOS 6 构建 所以我切换到 Xcode 4 5 和 iOS 6 但是我我面临很多问题 例如 Sqlite3 MobileCo
  • 摩卡与 NodeJS 断言断言挂起/超时(假)而不是错误

    我有这样的摩卡测试 describe sabah beforeEach sabahStrategy filter strats name sabah2 0 strat it article list should be populated
  • 我如何模拟 FromSql() 方法?

    我想知道除了构建一个包装器来嘲笑之外还有什么方法吗FromSql 我知道这个方法是静态的 但是因为他们添加了类似的东西AddEntityFrameworkInMemoryDatabase对于实体框架核心 我认为也可能有一个解决方案 我在我的