2012-05-28 74 views
2

假设我们有一个订单类与方法称为批准。当调用此方法时,它会检查某些条件并将订单置于Approved状态或引发异常。在服务层,我们已经得到的东西是这样的:状态与基于交互的测试

var order = _repository.Single(o => o.ID == orderID); 
order.Approve(); 
_context.SaveChanges(); // or _session.SaveChanges(); 

有2种方式来测试这个方法,我想听听您对此的见解:

解决方案1 ​​:存根存储库返回一个Order对象。然后声明订单处于“已批准”状态。

解决方案2:存根存储库以返回模拟订单对象。断言Approve()方法被调用。

解决方案1更简单,我个人更倾向于基于状态的测试,以基于交互的测试,因为后者可以针对实现细节并应该避免。但是,我认为测试指定订单处于Approved状态并不是此服务方法的关注点。我认为我们需要一个单独的Order类测试方法来测试是否抛出异常或Order的状态改变为Approved。

解决方案2可能听起来合乎逻辑,因为我们将审批订单的责任委托给订单类本身。因此,也许我们需要针对此服务方法进行2次测试:一次确保它将审批订单的任务委托给订单类,并确保它保存更改。

你对此有何认识?你更喜欢哪种解决方案?

干杯

回答

4

单元测试是测试观察到的行为是否符合预期/规范。

您的问题的答案归结为您认为在此情况下的“预期行为”:a)如果预期的行为是在调用服务方法后订单处于批准状态,则测试状态; b)如果预期的行为是批准操作被委托,则测试方法调用。

在这两种情况下,您都需要测试Order对象的行为(以便呼叫Approve()将状态更改为已批准状态)。

第二种解决方案可以很好地解耦两个对象的行为,但是如果订单可以处于批准状态的多种方式(并且这就是您正在测试的内容 - 情况a)),则你无谓地限制了接受的行为。

此外,我会创建一个单独的测试用于测试保存部分,如果这不是审批部分必需的