测试异常的正确方法
本文关键字:方法 异常 测试 | 更新日期: 2023-09-27 18:34:57
我在一个有80%简单逻辑和20%复杂逻辑的项目上做TDD。如果某些方法抛出错误,我发现自己会测试很多,并想知道正确的方法。我使用 NUnit 和 JustMock。
我有两种方法可以做到这一点。使用 ExpectException 属性,并指定类型。或按如下方式编写。写如下的优点是,我也可以断言 exception.message(如果我做了一个自定义的(,如果测试失败,我也会显示 exception.message。但我想和其他人一起检查你是怎么做到的。所以总结一下:
- 对这样的异常进行大量测试是否正常?
- 这是正确的方法吗:
只是为了解释:供应商提供某些合同,一个部门接受一份合同,但不能与同一供应商签订多份合同(但可以与不同的供应商签订不同的合同(
[Test]
public void Accepting_more_than_one_contract_from_supplier_throws_exception()
{
//Arrange
var department = new Department(Guid.NewGuid(), "1234");
var supplier = Mock.Create<Supplier>();
var contract1 = Mock.Create<DeliveryContract>();
var contract2 = Mock.Create<DeliveryContract>();
var id = Guid.NewGuid();
supplier.Arrange(x => x.Id).Returns(id);
contract1.Arrange(x => x.Supplier).Returns(supplier);
contract2.Arrange(x => x.Supplier).Returns(supplier);
//Act
department.AcceptContract(contract1);
//Assert
try
{
department.AcceptContract(contract2);
Assert.Fail("Duplicate contract with supplier did not throw an exception");
}
catch (Exception ex)
{
Assert.AreEqual(typeof(ArgumentException),ex.GetType(),ex.Message);
}
}
您可以使用 Assert.Throws 方法:
Assert.Throws<ArgumentException>(() => department.AcceptContract(contract2));
或
Assert.Throws<ArgumentException>(() => department.AcceptContract(contract2), "some message");
正如
@Ufuk所说。使用 T 为异常类型的Assert.Throws<T>
。
如果您还想检查异常消息,请使用以下方法之一:
T Assert.Throws<T>( TestDelegate code, string message );
T Assert.Throws<T>( TestDelegate code, string message,
params object[] parms);
顺便说一下,您为测试创建的数据不应该是模拟数据,而应该是存根。我所说的存根是指仅包含测试数据的对象,在您的情况下,您为对象提供行为 - 而不是数据。
我建议你使用NBuilder code.google.com/p/nbuilder/。您可以通过它创建清晰的存根。它还具有创建对象的极大灵活性,它们可以随机创建或完全为您的测试用例做好准备。
在您的情况下的用法:
var supplierStub = Builder<Supplier> .With(supplier => supplier.Id = id) .Build(); var contractsStub = Builder<DeliveryContract>.CreateListOfSize(2) .All() .With(contract => contract.Supplier = supplierStub) .Build();