异步列表的xUnit-mocked方法返回null



这是一件奇怪的事情-当我运行单元测试并将断点放在return Unit.Value;行时,我会看到someResult值为null-但当我手动将调试器的黄色箭头再次移动到前一行var someResult = await _myRepository.DoSomething(cancellationToken);时,someResult变量不为null并包含我的对象-为什么会发生这种情况?

单元测试片段:

//Arrange
var myList = new List<MyTable> { new MyTable() };
var myRepository = Substitute.For<IMyRepository>();
myRepository.DoSomething(Arg.Any<CancellationToken>()).Returns(myList);
var command = Substitute.For<MyCommand>();
//Act
var sut = new MyCommandHandler(myRepository);
await sut.Handle(command, Arg.Any<CancellationToken>());

我也试过:

myRepository.DoSomething(Arg.Any<CancellationToken>()).Returns(Task.FromResult(myList));

测试类别:

public class MyCommandHandler : ICommandHandler<MyCommand, Unit>
{
private readonly IMyRepository _myRepository;
public MyCommandHandler(IMyRepository myRepository)
{
_myRepository = myRepository ?? throw new ArgumentNullException(nameof(myRepository));
}
public async Task<Unit> Handle(MyCommand command, CancellationToken cancellationToken)
{
var someResult = await _myRepository.DoSomething(cancellationToken);
...
return Unit.Value;
}
}
public class MyRepository : IMyRepository
{
private readonly MyDbContext _context;
public MyRepository(MyDbContext context)
{
_context = context;
}
public async Task<List<MyTable>> DoSomething(CancellationToken cancellationToken = default)
{
return await _context.MyTable
.AsNoTracking()
.Where(...)
.ToListAsync(cancellationToken);
}
}

我认为Handle调用中的Arg.Any<CancellationToken>()匹配器是问题所在。

更改

await sut.Handle(command, Arg.Any<CancellationToken>());

await sut.Handle(command, default);

测试成功了。匹配器用于配置替换和检查接收到的调用,而不是用于实际调用本身。

可以在这里找到一个工作示例。我没有足够的时间继续复制Unit和它的用法,但能够观察并解决没有它时遇到的相同问题。

最新更新