如何使Task失败然后断言异常

时间:2019-06-18 08:53:47

标签: c# unit-testing testing async-await xunit

我正在编写大量测试来测试负面场景,因此基本上,当任务失败时,我需要检查是否抛出了正确的异常类型以及消息是否正确。我通过谷歌搜索尝试过的是这个

public async void TaskToTest_OnFailGiveException()
{
    var info = new Info();

    var ex = await Record.ExceptionAsync(() => info.TaskToTest());

        Assert.NotNull(ex);
        Assert.IsType<Exception>(ex);
}

以及用于测试消息的

public void TaskToTest_OnFailGiveException()
{
    var info = new Info();

    var ex = Assert.ThrowsAsync<Exception>(() => info.TaskToTest());

        Assert.NotNull(ex.Exception);
        Assert.Equal(ex.Exception.Message, $"Failed to insert the info");
}

它们两者的问题在于任务不会失败,因此到那里它不会给要声明的任何异常。我知道,如果我想模拟一个任务会带来正回报,我可以使用info.TaskToTest().Returns(Task.CompletedTask),但是我没有找到它的失败变体。有什么方法可以确保任务失败,以便我可以测试异常?

这是我尝试使之失败的任务

public virtual async Task TaskToTest()
{
    bool result = await _database.InsertOrUpdateInfo(State.InfoID, _unhandledInfo.Count > 0 ? JsonConvert.SerializeObject(_unhandledInfo) : string.Empty);
    if (!result)
    {
        _logger.LogError($"Error while calling InsertOrUpdateInfo. Info: {State.INfoID}");
        var exception = new Exception("Failed to insert the info");
        throw exception;
    }
}

1 个答案:

答案 0 :(得分:1)

被测方法似乎正在对数据库进行外部调用。

您需要模拟数据库调用以返回false,以便被测方法流入引发异常的条件语句中。

public async Task TaskToTest_OnFailGiveException() {
    //Arrange

    //...mock database and setup accordingly
    //eg: database.InsertOrUpdateInfo(...).ReturnsAsync(false);

    var info = new Info(database);

    //Act
    var ex = await Record.ExceptionAsync(() => info.TaskToTest());

    //Assert
    Assert.NotNull(ex);
    Assert.IsType<Exception>(ex);
}

这应该为测试提供预期的用例。