Unit testing 确保方法A在方法B之后调用的单元测试
我有一个与某个对象交互的代码,然后应该对它调用finish()方法Unit testing 确保方法A在方法B之后调用的单元测试,unit-testing,Unit Testing,我有一个与某个对象交互的代码,然后应该对它调用finish()方法 void completeTransaction(PaymentTransaction transaction) { recordTransaction(transaction.getId()); transaction.finish(); } PaymentTransaction是一些第三方类,finish()之后的行为是未定义的-它可能会引发异常或只是无声地失败 我需要编写一个单元测试,该测试通过了,
void completeTransaction(PaymentTransaction transaction) {
recordTransaction(transaction.getId());
transaction.finish();
}
PaymentTransaction是一些第三方类,finish()
之后的行为是未定义的-它可能会引发异常或只是无声地失败
我需要编写一个单元测试,该测试通过了,并且只有通过了:
recordTransaction(transaction.getId())
调用transaction.finish()
调用transaction.finish()
在recordTransaction(transaction.getId())之后调用
void completeTransaction(PaymentTransaction transaction) {
transaction.finish();
recordTransaction(transaction.getId()); //oops
}
第一个条件的测试用例:
void testCompleteTransaction_TransactionRecorded() {
completeTransaction(transactionMock);
// assert that recordTransaction(transaction.getId())
// called with correct argument
completeTransaction(付款交易)
}
关于第二个问题:
void testCompleteTransaction_TransactionCompleted() {
completeTransaction(transactionMock);
// assert that transaction.finish() called
}
我想知道如何通过测试用例强制执行第三个条件。您的测试用例毫无意义: 方法在代码中的调用顺序如下: 在单元测试中,您不仅应该调用一些方法,还应该测试正确的结果 但如果你想找点乐子:
public testNonsenseTest() {
int i = 0;
PaymentTransaction transaction = new PaymentTransaction();
int transactionId = transaction.getId());
recordTransaction(transactionId);
i++;
assertEquals(1, i);
transaction.finish();
i++;
assertEquals(2, i);
}
您可以传入一个伪
PaymentTransaction
,该事务覆盖finish()
和getId()
,这样finish()
在调用getId()
时,如果没有设置某个内部标志,就会引发异常
public class FakePaymentTransaction {
private bool _getIdWasCalled = false;
public override void finish () {
if (!_getIdWasCalled) {
throw new Exception ("getId wasn't called first!");
}
}
public override /* your return type */ getId() {
_getIdWasCalled = true;
// Some other logic to return your specified return type
}
}
现在,当您将其传递到SUT时,您将看到调用的顺序是否正确。您需要的是一个可以验证调用顺序是否符合预期的模拟。你可以按照James D'Angelo的回答中的建议,针对具体的案例展开你自己的研究,或者你可以创建一个更通用的类似的研究 或者您可以使用一个好的模拟框架提供的工具
例如,Mockito有一个验证器,可以验证来自单个或多个模拟的模拟方法的调用顺序。涉及哪些测试框架。这是什么语言?您可以显示1和2的现有测试吗?您缺少一些解释:只要RecordTransaction不创建线程,当您从调用返回时,它就完成了。是否要在recordTransaction()中等待另一个线程?@Damien_The_unsiver:这段代码是用某种虚构的语言编写的,用于将问题与特定语言的详细信息分开。@AlexWien:否,所有这些都是关于以正确的顺序调用方法。我编辑了我的问题,以强调重点并使其更加清晰。我认为它们在白盒单元测试方面是有意义的:我定义了代码预期要做的事情。这里的结果是记录事务并确保它已完成。至少它是有用的,您可以在启动测试用例时调试到其中。您无法测试transactionId是否与另一个transactionId不同。对不起,我忘了在测试用例中进行实际调用。这就是你的观点?不知道你的代码是很难的。如果一个交易不成功会发生什么?它会抛出一个例外吗?如果是,那么类似于我的测试是有意义的,它表明,至少可以在没有异常的情况下调用methdos。recordTranaction()的返回值是多少?它是布尔值还是空值。如果是布尔值:您可以执行assertTrue(recordTransaction(TrasActionId));非常感谢。我想没有比这更轻量级的解决方案了。我不同意。这是一个相当轻量级的解决方案。您可以控制SUT的输入,以便准确定义内部发生的事情。没有什么“神奇”的方法可以做到这一点。我同意。因为OP中没有语言,我觉得我不能给出更具体的语言/框架的答案。@JamesD'Angelo:你的答案很好,我投了赞成票。我只是觉得一些框架提供的帮助可能也很有用。谢谢大家的支持。我不是故意让人觉得我是在自卫。只希望能提供更多信息,以便我们能给出更好的答案。=)