【问题标题】:How to moq FromSqlInterpolated?如何最小起订量 FromSqlInterpolated?
【发布时间】:2021-08-22 08:27:33
【问题描述】:

请帮助从上下文中模拟 FromSqlInterpolated 方法。 我有一个简单的方法:

public List<UserTag> PrintUserTag(string userId)
    {
        return this.context.UserTag.FromSqlInterpolated($"ctc_sp_UserTag {userId}").ToList();
    }

我写了一个测试:

[Fact]
    public void UserTagTest_ReturnsSuccessResult()
    {
        string userId = "7C8FFA01-94FC-42EA-9C43-5CA7FD0400D1";

        List<UserTag> userTags = new List<UserTag>()
        {
            new UserTag()
            {
                Id = userId,
                UserTagName = "TestName",
                // ..... and others lines
            }
        };

        var mockDbSet = userTags.AsDbSetMock();
        mockContext.Setup(x => x.UserTags).Returns(mockDbSet.Object);
        mockContext.Setup(a =>
                a.Set<UserTag>().FromSqlInterpolated<UserTag>(It.IsAny<FormattableString>())).Returns(mockDbSet.Object);

        var actual = this.repo.PrintUserTag(userId);

        Assert.NotNull(actual);
        // And other Asserts
    }

并收到此异常:

Message: 
System.NotSupportedException : Unsupported expression: ... => ....FromSqlInterpolated<UserTags>(It.IsAny<FormattableString>())
Extension methods (here: RelationalQueryableExtensions.FromSqlInterpolated) may not be used in setup / verification expressions.

如何模拟或重写这一行:

mockContext.Setup(a =>
                a.Set<UserTag>().FromSqlInterpolated<UserTag>(It.IsAny<FormattableString>())).Returns(mockDbSet.Object);

【问题讨论】:

  • 不要为此使用模拟。如果您想进行集成测试,请针对真实数据库(如 LocalDB 实例)进行测试,或者将您的测试提升到更高级别,您不测试具体的数据库层但使用接口提取数据访问,如果您愿意做真正的单元测试。请参阅this 了解更多信息。
  • 你应该改为mockDbSet.Setup(x =&gt; x.FromSqlInterpolated(...))

标签: c# moq xunit


【解决方案1】:

你不能直接模拟FromSqlInterpolated,因为它是扩展方法。在幕后,它在DbSet&lt;T&gt; 可查询提供程序上调用CreateQuery&lt;T&gt;

如果您不想设置集成测试,我是作者的库EntityFrameworkCore.Testing 可以做到。如果您想自己模拟一下,我很乐意为您指出您需要的代码,但我需要知道您使用的是哪个版本的 EFCore,因为实现会有所不同。

集成测试与模拟是一个固执己见的话题。我同意 MS 的建议,因为您不应该模拟 DbContext - 这是您不拥有的复杂依赖项,并且很难在模拟中模拟行为。通常我使用内存提供程序,根据我的经验,它是一个可靠的假货,但它不能进行关系操作。

我将关系操作视为我可以控制的众所周知的依赖项——它们通常是我的存储过程或函数,我拥有它们——所以我使用上述库来模拟它们没有问题。他们仍然需要在某个时候进行测试,但至少这样我就有了选择。

【讨论】:

    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 2015-12-23
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多