Search code examples
unit-testingbusiness-rules

How to unit test business rules?


I need a unit test to make sure I am accumulating vacation hours properly. But vacation hours accumulate according to a business rule, if the rule changes, then the unit test breaks.

Is this acceptable? Should I expose the rule through a method and then call that method from both my code and my test to ensure that the unit test isn't so fragile?

My question is: What is the right way to unit test business rules that may change?


Solution

  • Your tests should ensure that the code properly obeys the business rule. Therefore, I wouldn't write tests that go around the business rule or rely on the business rule code itself. Rather, when the business rule changes, I would first change the test to reflect the new business rule, then when my code no longer passes the test, go and fix the code so that it passes the test.

    What you don't want to happen is to write your test so that when you change how the same business rule is applied, that your test breaks. That's easier said than done, but essentially what you want to test is the minimum required to implement the rule without dictating too narrowly how the code is implemented. If the outcome of the rule is different, though, then you should be changing the test first, then the code to match it.

    You also don't want the test to be coupled to specific data, either. Say when doing a tax calculation, your test shouldn't be written to assume that the class under test uses 5% as the tax. Instead, you should write your test so that it supplies the tax percentage, and then checks that the calculation is done correctly. Presumably, you'll have a range of values to test to make sure that out of range values are caught as well. One result of this is that you'll have a better design as this will help you to avoid hard-coded values and make your production code more flexible to changes in data.