在Nunit,C#中验证ArgumentException及其消息
本文关键字:ArgumentException 消息 验证 Nunit | 更新日期: 2023-09-27 18:24:37
在Nunit的测试程序中,我想通过验证消息来验证它是否得到了write Argument Exception。
[Test]
public void ArgumentsWorkbookNameException()
{
const string workbookName = "Tester.xls";
var args = new[] { workbookName, "Sheet1", "Source3.csv", "Sheet2", "Source4.csv" };
Assert.Throws(typeof(ArgumentException), delegate { var appargs = new ApplicationArguments(args); }, "Invalid ending parameter of the workbook. Please use .xlsx");
}
经过测试,当我在主程序中修改消息时,这是不起作用的。
int wbLength = args[0].Length;
// Telling the user to type in the correct workbook name file.
if (args[0].Substring(wbLength-5,5)!=".xlsx")
{
throw new ArgumentException(
"Invalid ending parameter of the workbook. Please use .xlsx random random");
}
不管我是否更改了消息,单元测试仍然通过。
我该怎么做?或者C#中没有这样的东西。我的同事说Ruby和RSPEC也有类似的选择,但他对C#并不是100%确定。
使用fluent接口创建断言:
Assert.That(() => new ApplicationArguments(args),
Throws.TypeOf<ArgumentException>()
.With.Message.EqualTo("Invalid ending parameter of the workbook. Please use .xlsx random random"));
我同意Jon的观点:;这样的测试是不必要的脆性";。但是,至少有两种方法可以检查异常消息:
1:Assert.Throws
返回一个异常,因此您可以对其消息进行断言:
var exception = Assert.Throws<ArgumentException>(() => new ApplicationArguments(args));
Assert.AreEqual("Invalid ending parameter of the workbook. Please use .xlsx random random", exception.Message);
2:[历史]在NUnit 3之前,您还可以使用ExpectedException
属性。但是,请注意,属性在整个测试代码中等待异常,而不仅仅是在抛出异常的代码中。因此,不建议使用此属性。
[Test]
[ExpectedException(typeof(ArgumentException), ExpectedMessage = "Invalid ending parameter of the workbook. Please use .xlsx random random")]
public void ArgumentsWorkbookNameException()
{
const string workbookName = "Tester.xls";
var args = new[] { workbookName, "Sheet1", "Source3.csv", "Sheet2", "Source4.csv" };
new ApplicationArguments(args);
}
- 您也可以使用FluentAssessments来执行此操作,例如
subject.Invoking(y => y.Foo("Hello"))
.Should().Throw<InvalidOperationException>()
.WithMessage("Hello is not allowed at this moment");
Assert.Throws
中的消息参数不是预期的异常消息;如果测试失败,这是断言失败时要包含的错误消息。
我不认为NUnit支持开箱即用地测试异常消息,而且我认为这样的测试无论如何都是不必要的脆弱。如果你真的想写自己的这种辅助方法,你可以这样做,但我个人不鼓励这样做。(我也很少指定测试失败消息,除非它包含一些诊断信息。如果测试失败,我无论如何都会查看测试,所以消息不会增加太多内容。)
不过,为了简单起见,我会鼓励您使用泛型重载和lambda表达式:
Assert.Throws<ArgumentException>(() => new ApplicationArguments(args));
(顺便说一句,如果这是您的实际代码,那么还有其他问题-尝试将new[] { "xyz" }
作为参数传递…)
在.NET Core 3.1 MSTest项目中,我就是这样做的。
[TestMethod]
public async Task SaveItemAsync_NameIsNull_ThrowsException()
{
var item = new Item
{
Name = null
};
var result = await Assert.ThrowsExceptionAsync<ArgumentException>(() => _service.SaveItemAsync(item));
Assert.AreEqual("The item's name must be set.", result.Message);
}