raghavankl
raghavankl

Reputation: 113

Using junit build base unit tests and abstract validation

Assume that I am building a monthly subscription charging feature for a mobile app, there are multiple ways to charge the bill. It can be through Apple Pay, Google wallet, paypal, visa/master depends on the platform. Each provider has their own implementation and respective JUnit tests ( as they are using Java).

To evaluate few basic functionalities, there are few cases which every implementation has to validate. So, the plan is to write base tests and call an abstract validate method.

Here is my approach,

public abstract class BaseBillingTest 
{
 public abstract BillCharger getBillCharger();
 public abstract void ValidateTest1(Bill input, Bill output); 
 public void tests_case_1(){
  Bill input = new Bill(<some value>);
  Bill Output = getBillCharger().charge(input);
  ValidateTest1(input, output);
 }
}

Any derived test class will implement the abstract methods, so it has the responsibility to implement the validate methods. The derived test class need not know what is happening in the base test, as they can just validate the output based on the input.

Any suggestions to approach this in a more elegant fashion ? Are there any design patterns which I can apply in this scenario ?

Upvotes: 1

Views: 70

Answers (2)

Stephan Herrmann
Stephan Herrmann

Reputation: 8178

The original approach does, in fact, apply a design pattern, it's called Template Method.

OTOH, the questions has a slight smell of hunting for design patterns as a goal in its own right. Why bother, if they already have a solution at hand that fulfills functional (here: testing the right thing) as well as non-functional (here: clearly separating common parts from specifics) requirements. The one reason I would accept is: communication, as in: being able to give a name to the design so that co-workers quickly understand my intentions.

Upvotes: 0

Alexander Petrov
Alexander Petrov

Reputation: 9492

Your example of Inheritance in my opinion is not the optimal way to go for the two abstract methods. One is Constructional and the other is static - you validate one Bill against another.

In both cases inheritance is not the correct relationship here. You can use successfully Factory pattern for the "getBillCharger" or the more modern TestDataBuilders or ObjectMother pattern.

For the second method you can just use a helper class. If you need to invoke the same construction logic several times in a Test class you can use @Before

One important aspect is that if you place your tests_case_1 in super class you will be hiding parts of your logic and your tests will not be that obvious. I prefer more explicit and visible test cases therefore I would avoid this kind of setup.

Upvotes: 2

Related Questions