Test-Driven Development

Test-driven development is a process that assists in creating high quality, well designed, loosely coupled and maintainable code that can be refactored with confidence. The process relies on writing unit tests before creating the code that they validate.

We now have an opportunity for refactoring the code to make it cleaner and more readable. Firstly, the Deposit and Withdrawal classes are almost identical. We could introduce a base class for these that represents any transaction.

After these changes we can run the tests as a small regression test suite. All three tests should still pass, showing that we have not introduced any bugs.

One of the problems with the Transaction base class is that the value will always be positive. It would be useful if deposits were positive, as they increase balances, and withdrawals were negative. To achieve this we'll modify the Withdrawal class's constructor, as follows:

Running the tests will now show a failure because the negative value of a withdrawal is subtracted from the balance, increasing the balance rather than reducing it. This can be fixed by modifying the Withdraw method to add, rather than subtract, the value:

The tests now all pass again. However, making these changes has led to duplication; the contents of the Deposit and Withdraw methods of the Account class are now identical. This duplication could be removed by replacing the two methods with a single operation that can process any transaction. Let's call this method, "RecordTransaction". We'll start by modifying the two existing tests that cover the calls to Deposit and Withdraw, as follows:

The code here is not as clean as I would like. For example, it would be better if the value passed into the Withdrawal constructor could be obtained from the created object directly, rather than just being able to get the negated value. Alternatively we might rename the Value property of Transaction and its subclasses to a more appropriate name, such as BalanceAdjustmentValue. For the purposes of this article the current code will suffice.