Тест не пройден, если исключение выдается в другой части SUT (асинхронный поток) - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть такая система

class Sut
{
    IRepository _repo;

    public Sut(IRepository repo) { _repo = repo; }

    async Task Handle(Request request)
    {
         var entity  = new Entity(request.Id); //=> if Id is not ok the Entity throws Exception

         _repo.Save(entity);
    }
}

Это тест

[Fact]
public async Task Test_Save()
{
    Mock<IRepository> repositoryMock = new Mock<IRepository>();

    repositoryMock
        .Setup(repo => repo.Save(It.IsAny<Entity>()))
        .Returns(Task.CompletedTask);

    var sut = new Sut(repositoryMock.Object);

    /// Act
    Action action = async () => await sut.Handle(new Request { Id = default(Guid)});

    /// Assert 
    Assert.Throws<Exception>(action);
    repositoryMock.Verify(repo => repo.Save(It.IsAny<Entity>(), Times.Never);
}

Итак, Entity имеет проверку по умолчанию Guid, являющуюсяперешел на это.Если значение по умолчанию передано, оно выдаст исключение.

Исключение выдается, но тест завершается с этим сообщением.

Сообщение: Assert.Throws ()

Ожидается сбой: typeof (System.Exception)

Факт: (не было сгенерировано исключение)

Тест никогда не вызывает

repositoryMock.Verify(repo => repo.Save(It.IsAny<Entity>(), Times.Never);

, он прервется в этой строке

Почему этои как решить эту ситуацию?

Assert.Throws<Exception>(action);

ОБНОВЛЕНИЕ

 public Entity(Guid id)
 {
     if (default(Guid) == id) throw new Exception("cannot have a default value for id");
     Id = id;
 }

1 Ответ

0 голосов
/ 28 ноября 2018

Action action = async () => ... в основном async void, что означает, что выброшенное исключение не будет поймано.

Измените синтаксис, чтобы использовать Func<Task> вместе с Assert.ThrowsAsync

[Fact]
public async Task Test_Save() {
    //Arrange
    var repositoryMock = new Mock<IRepository>();

    repositoryMock
        .Setup(repo => repo.Save(It.IsAny<Entity>()))
        .Returns(Task.CompletedTask);

    var sut = new Sut(repositoryMock.Object);

    /// Act
    AsyncTestDelegate act = () => sut.Handle(new Request { Id = default(Guid)});

    /// Assert 
    await Assert.ThrowsAsync<Exception>(act);
    repositoryMock.Verify(repo => repo.Save(It.IsAny<Entity>(), Times.Never);
}

Ссылка Assert.ThrowsAsync

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...