小编典典

使用 XUnit 断言异常

all

我是 XUnit 和 Moq 的新手。我有一个将字符串作为参数的方法。如何使用 XUnit 处理异常。

[Fact]
public void ProfileRepository_GetSettingsForUserIDWithInvalidArguments_ThrowsArgumentException() {
    //arrange
    ProfileRepository profiles = new ProfileRepository();
    //act
    var result = profiles.GetSettingsForUserID("");
    //assert
    //The below statement is not working as expected.
    Assert.Throws<ArgumentException>(() => profiles.GetSettingsForUserID(""));
}

被测方法

public IEnumerable<Setting> GetSettingsForUserID(string userid)
{            
    if (string.IsNullOrWhiteSpace(userid)) throw new ArgumentException("User Id Cannot be null");
    var s = profiles.Where(e => e.UserID == userid).SelectMany(e => e.Settings);
    return s;
}

阅读 139

收藏
2022-07-04

共1个答案

小编典典

Assert.Throws表达式将捕获异常并断言类型。但是,您在断言表达式之外调用被测方法,因此测试用例失败。

[Fact]
public void ProfileRepository_GetSettingsForUserIDWithInvalidArguments_ThrowsArgumentException()
{
    //arrange
    ProfileRepository profiles = new ProfileRepository();
    // act & assert
    Assert.Throws<ArgumentException>(() => profiles.GetSettingsForUserID(""));
}

如果一心要遵循 AAA,您可以将操作提取到它自己的变量中。

[Fact]
public void ProfileRepository_GetSettingsForUserIDWithInvalidArguments_ThrowsArgumentException()
{
    //arrange
    ProfileRepository profiles = new ProfileRepository();
    //act
    Action act = () => profiles.GetSettingsForUserID("");
    //assert
    ArgumentException exception = Assert.Throws<ArgumentException>(act);
    //The thrown exception can be used for even more detailed assertions.
    Assert.Equal("expected error message here", exception.Message);
}

请注意异常如何也可用于更详细的断言

如果进行异步测试,
Assert.ThrowsAsync
与前面给出的示例类似,除了应该等待断言之外,

public async Task Some_Async_Test() {

    //...

    //Act
    Func<Task> act = () => subject.SomeMethodAsync();

    //Assert
    var exception = await Assert.ThrowsAsync<InvalidOperationException>(act);

    //...
}
2022-07-04