I have a code which interacts with some object and then should call finish() method on it.
void completeTransaction(PaymentTransaction transaction) {
recordTransaction(transaction.getId());
transaction.finish();
}
PaymentTransaction is some third-party class which behaviour after finish() is undefined — it may throw an exception or just fail silently.
I need to write a unit test which passes then and only then:
recordTransaction(transaction.getId())calledtransaction.finish()calledtransaction.finish()called afterrecordTransaction(transaction.getId())
Test satisfying the above conditions should prohibit code like this:
void completeTransaction(PaymentTransaction transaction) {
transaction.finish();
recordTransaction(transaction.getId()); //oops
}
Test case for the first condition:
void testCompleteTransaction_TransactionRecorded() {
completeTransaction(transactionMock);
// assert that recordTransaction(transaction.getId())
// called with correct argument
completeTransaction(PaymentTransaction transaction)
}
For the second one:
void testCompleteTransaction_TransactionCompleted() {
completeTransaction(transactionMock);
// assert that transaction.finish() called
}
I wonder how can I enforce the 3rd condition via test case.
You could pass in a fake
PaymentTransactionthat overridesfinish()andgetId()such thatfinish()throws an exception if some internal flag isn’t set whengetId()is called.Now when you pass it into your SUT, you will see if the calls were made in the right order.