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

C#单元测试中Mock的DapperWrapper GetAll方法返回null如何解决

问题排查及修复方案

第一个GetAuthor方法测试的问题

两个核心错误导致Mock匹配失败返回null:

  • 参数匹配失败:Setup时传入的SqlConnection实例是你自己在测试方法里新建的,而仓储中调用GetAll用的连接是GetDbconnection()返回的新实例,两个实例引用不一致。Moq默认按引用匹配参数,因此规则不触发,返回默认值null。
  • 未等待异步方法:调用newsRepository.GetAuthor()时没有加await,不仅拿不到真实返回结果,还可能导致测试提前结束,Mock逻辑未被触发。

修正后的测试代码示例:

public async Task TestMethodTestAsync()
{
    var expectedQuery = "SELECT TOP (10) liAuthorId as Id, sFirstName as FirstName, sLastName as LastName from dbo.Authors";
    List<Author> author = new List<Author> {
        new Author { Id = 1, FirstName = "abc", LastName = "def" },
        // 其余模拟数据保持不变即可
    };

    // 用It.IsAny<IDbConnection>匹配任意连接实例,不需要自己构造连接对象
    mockDapperWrapper.Setup(x => x.GetAll<Author>(
        It.IsAny<IDbConnection>(), 
        expectedQuery, 
        null, 
        CommandType.Text))
    .Returns(author);

    // 加await等待异步方法执行完成
    var result = await newsRepository.GetAuthor();
    // 后续添加自己的断言逻辑
}

第二个GetNewsArticle方法测试的问题

三处参数不匹配导致Mock规则失效:

  • 第三个参数你在Setup里传了null,但仓储实际调用时传了内部实例化的DynamicParameters对象,参数不一致
  • 第四个参数你在Setup里传了CommandType.Text,但仓储实际调用时用的是CommandType.StoredProcedure,枚举值完全不匹配
  • 如果你直接用测试里实例化的DynamicParameters做匹配,和仓储内部new的实例引用不一致,也会匹配失败

修正后的测试代码示例:

public async Task Should_Fetch_NewsArticle_Data()
{
    string expectedQuery = "[KafkaPublisher].[GetNewsArticle]";
    List<NewsArticle> article = new List<NewsArticle> {
        new NewsArticle { Timestamp = 1, Version = 1, Headline = "hl", Body = "b1", AuthorId = 1 },
        // 其余模拟数据保持不变即可
    };

    // 参数和实际调用完全对齐:用It.IsAny匹配连接和动态参数,CommandType选StoredProcedure
    mockDapperWrapper.Setup(x => x.GetAll<NewsArticle>(
        It.IsAny<IDbConnection>(), 
        expectedQuery, 
        It.IsAny<DynamicParameters>(), 
        CommandType.StoredProcedure))
    .Returns(article);

    var result = await newsRepository.GetNewsArticle();
    // 后续添加自己的断言逻辑
}

如果需要更严谨的参数匹配,也可以对DynamicParameters的内容做校验,替换It.IsAny<DynamicParameters>()即可:

It.Is<DynamicParameters>(p => 
    p.ParameterNames.Contains("@ReturnValue") 
    && p.ParameterNames.Contains("@Message"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:27:03