xUnit - смоделированный метод для asyn c List возвращает null - PullRequest
0 голосов
/ 25 апреля 2020

Вот странная вещь - когда я запускаю модульный тест и ставлю точку останова на строку return Unit.Value;, я вижу, что значение someResult равно нулю - но когда я вручную перемещаю желтую стрелку отладчика, предыдущая снова строка var someResult = await _myRepository.DoSomething(cancellationToken);, тогда переменная someResult не равна нулю и содержит мой объект - почему это происходит?

Фрагмент модульного теста:

//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);
    }
}

1 Ответ

2 голосов
/ 26 апреля 2020

Я думаю, что Arg.Any<CancellationToken>() сопоставитель в вашем Handle вызове является проблемой.

При изменении

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

на

await sut.Handle(command, default);

тест работает , Сопоставители предназначены для настройки замены и проверки полученных вызовов, а не для самого фактического вызова.

Рабочий пример можно найти здесь . Мне не хватило go для репликации Unit и его использования, но я смог наблюдать и решить ту же проблему, что и у вас, без нее.

...