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