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
相关产品推荐
相关产品推荐

