Nunit 测试一个既执行某些操作又抛出异常的方法

Nunit 测试一个既执行某些操作又抛出异常的方法,nunit,moq,Nunit,Moq,我开始使用TDD(和MoQ)。我有一个方法,它接收订单并为该订单创建唯一的CustomerId public class CustomerService { public CustomerService(IOrderRepository orderRepo) { _orderRepo = orderRepo; } public string Create(Order order)

我开始使用TDD(和MoQ)。我有一个方法,它接收订单并为该订单创建唯一的CustomerId

public class CustomerService
    {

        public CustomerService(IOrderRepository orderRepo)
        {
            _orderRepo = orderRepo;
        }

        public string Create(Order order)
        {
            //1. Save the Order that comes in, irrespective of being valid or not.
            _orderRepo.Save(order);

            //2. If the order is invalid, throw an exception.
            if (!isValid(order))
                throw new ArgumentException();

            //3. Create a Customer, generate a unique CustomerId and return that.
            return createCustomerAndGenerateCustomerId(order);
        }

    }
以下测试似乎无法正常工作:

    [Test]
    [ExpectedException(typeof(ArgumentException))]
    public void Create_WhenPassedInvalidOrder_StillPersistsIt()
    {
        //Arrange
        var order = new Order(); //This is invalid, as it has some mandatory fields missing
        var mockOrderRepo = new Mock<IOrderRepository>();
        var customerService = new CustomerService(mockOrderRepo.Object);

        //Act
        customerService.Create(order);  //This should call Save() on the order repo, but still throw an exception.

        //Assert
        mockOrderRepo.Verify(o => o.Save(order), Times.Once());
    }
[测试]
[ExpectedException(typeof(ArgumentException))]
当AssedValidOrder_StillPersistsIt()时创建公共void_
{
//安排
var order=new order();//这是无效的,因为它缺少一些必填字段
var mockorderepo=new Mock();
var customerService=新的customerService(mockOrderRepo.Object);
//表演
customerService.Create(order);//这应该调用order repo上的Save(),但仍然会引发异常。
//断言
验证(o=>o.Save(order),Times.Once());
}

即使我没有调用_orderepo.Save(),此测试也始终通过。我做错了什么?

在此场景中不能使用
ExpectedException
,因为Nunit将在测试级别尝试/捕获异常,因此您的
mockOrderRepo.Verify
永远不会被调用

因此,您需要手动尝试捕获您的
customerService.Create
调用-如果您想手动断言抛出的异常-或者您需要:

[测试]
当AssedValidOrder_StillPersistsIt()时创建公共void_
{
//安排
var order=新订单();
var mockorderepo=new Mock();
var customerService=新的customerService(mockOrderRepo.Object);
//表演
Assert.Throws(()=>customerService.Create(order));
//断言
验证(o=>o.Save(order),Times.Once());
}

您必须决定要在测试中断言什么:是断言抛出了异常,还是断言调用了
Save
方法,因为在使用
ExpectedException
属性时,您无法同时执行这两项操作……如果我尝试调试,程序执行不会在抛出新ArgumentException()时停止,而是在方法中继续执行。这是由于ExpectedException造成的吗?您的意思是排除
[ExpectedException(typeof(ArgumentException))]
而使用
Assert.Throws
?是的,很抱歉,我在示例代码中保留了该属性,现在已删除。是的,现在我可以检查有效和无效的顺序。谢谢