如何对无返回值的异步MongoDB添加函数进行单元测试?
正确测试无返回值异步Add函数的方法
你的测试代码存在几个问题:没必要用DI容器初始化依赖,断言逻辑完全错误,还有测试方法缺少[Fact]标记。针对无返回值的AddSampleSetAsync,核心是验证依赖的InsertOneAsync是否被正确调用,而不是比较返回值(因为它仅返回Task,无业务返回结果)。
步骤1:简化测试类初始化
不需要用ServiceCollection,直接用NSubstitute创建模拟的IMongoCollection<SampleSet>,然后直接实例化SampleRepository即可,测试逻辑会更简洁。
步骤2:测试有效输入的Add方法
对于无返回值的方法,我们要验证三点:
- 仓储是否调用了
IMongoCollection的InsertOneAsync - 调用时传入的参数是否和我们传入的
SampleSet一致 - 调用次数是否正确(这里应该是1次)
用NSubstitute的Received()方法就能实现这个验证。
步骤3:测试无效输入(可选)
如果业务逻辑要求AddSampleSetAsync不能接受无效的SampleSet(比如null、空集合等),可以补充测试,验证传入无效值时的行为(比如是否抛出异常)。
修正后的完整测试代码
public class SamplesRepositoriesTests { private readonly IMongoCollection<SampleSet> _mongoCollection = Substitute.For<IMongoCollection<SampleSet>>(); private readonly ISampleRepository _samplesRepository; public SamplesRepositoriesTests() { // 直接初始化仓储,无需DI容器 _samplesRepository = new SampleRepository(_mongoCollection); } [Fact] // XUnit必须通过该标记识别测试方法 public async Task AddSampleSetAsync_ValidSampleSet_ShouldCallInsertOneAsyncOnce() { // 准备测试数据 var samples = new List<Sample> { new Sample("test", "{\"test\":\"test\"}") }; var testSampleSet = new SampleSet("test", samples, "test", DateTime.UtcNow); // 执行待测试方法 await _samplesRepository.AddSampleSetAsync(testSampleSet); // 验证:IMongoCollection的InsertOneAsync是否被恰好调用1次,参数为传入的testSampleSet await _mongoCollection.Received(1).InsertOneAsync(testSampleSet); } [Fact] public async Task AddSampleSetAsync_NullSampleSet_ShouldThrowArgumentNullException() { // 测试传入null的场景,验证是否抛出预期异常 await Assert.ThrowsAsync<ArgumentNullException>(() => _samplesRepository.AddSampleSetAsync(null!)); } }
关键说明
Received(1):验证目标方法被调用恰好1次,未调用或调用多次都会导致测试失败。Assert.ThrowsAsync:用于验证异步方法抛出指定类型的异常,适合测试无效输入的场景。- 移除不必要的DI容器:单元测试应尽量简化,直接构造依赖和被测试对象,避免引入额外复杂度。
内容的提问来源于stack exchange,提问作者ChAnViNi
相关产品推荐
相关产品推荐

