0

我在一个具有 80% 简单逻辑和 20% 复杂逻辑的项目上进行 TDD。如果某些方法抛出错误并想知道正确的方法,我会发现自己进行了很多测试。我使用 NUnit 和 JustMock。

我有两种方法可以做到这一点。使用 ExpectedException 属性,并指定类型。或者写如下。编写如下的专业人士是,我还可以断言 exception.message(如果我制作了自定义的),如果测试失败,我也会显示 exception.message。但我想和其他人一起检查你是如何做到的。所以总结一下:

  1. 对这样的异常进行大量测试是否正常?
  2. 这是正确的方法吗:

只是为了解释一下:供应商提供某些合同,部门接受一份合同但不能与同一供应商签订多份合同(但当然可以与不同供应商签订不同的合同)

    [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);
        }
    }
4

2 回答 2

6

您可以使用Assert.Throws方法:

Assert.Throws<ArgumentException>(() => department.AcceptContract(contract2));

或者

Assert.Throws<ArgumentException>(() => department.AcceptContract(contract2), "some message");
于 2013-10-12T08:38:57.457 回答
2

正如@Ufuk 所说。使用Assert.Throws<T>其中 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();

于 2013-10-12T09:00:51.330 回答