How should you write junit test cases for multiple implementations of the same interface?

Before asking a question, let me explain the current setup:

I have a service interface, say Service and one implementation, say ServiceImpl. This ServiceImpl uses some other services. All services are loaded as a bean on spring.

Now I want to write junit test cases for ServiceImpl. To do this, I use applicationContext to get the service bean and then call different methods to test it.

This looks fine for public methods, but how do you write test cases for private methods? Since we may not have the same private methods for different implementations?

Can anyone help me here what should be the preferred way of writing test cases?

+1


source to share


4 answers


The purist answer is that private methods are called for a reason !; -)

Turn the question around: ask only a spec (public) interface, how would you lay out a test plan before writing code? This interface describes the expected behavior of the object that implements it; if it is not tested at this level then something is wrong with the design.

For example, if we are a shipping company, we might have these (pseudo-coded) interfaces:

CapitalAsset {
    Money getPurchaseCost();
    Money getCurrentValue();
    Date  whenPurchased();
    ...
}

PeopleMover {
    Weight getVehicleWeight();
    int    getPersonCapacitly();
    int    getMilesOnFullTank();
    Money  getCostPerPersonMileFullyLoaded(Money fuelPerGallon);
    ...
}

      

and can have classes including the following:

Bus implements CapitalAsset, PeopleMover {
    Account getCurrentAdvertiser() {...}
    boolean getArticulated() {...}
    ...
}

Computer implements CapitalAsset {
    boolean isRacked() {...}
    ...
}

Van implements CapitalAsset, PeopleMover {
    boolean getWheelchairEnabled() {...}
    ...
}

      



When developing the concept and interface, CapitalAsset

we have to agree with the financial guys about how any instance should behave CapitalAsset

. We will write tests against CapitalAsset

that depend only on this convention; we should be able to run those tests on Bus

, Computer

and in the Van

same way, without any dependency on a particular class. Likewise for PeopleMover

.

If we need to test something about Bus

that does not depend on the general contract for CapitalAsset

and PeopleMover

, then we need separate bus tests.

If a particular concrete class has public methods that are so complex that TDD and / or BDD cannot clearly express the expected behavior, then again that is a hint that something is wrong. If there are private "helper" methods in a particular class, they must be there for a specific reason; the question should be asked, "If this assistant had a defect, what impact on social behavior (and how)?"

For legitimate, inherent complexity (i.e., coming from the problem area), it may be appropriate for a class to have private instances of helper classes that take responsibility for specific concepts. In this case, the helper class should be checked by itself.

A good rule of thumb:

If it's too hard to check, it's too hard!

+5


source


Private methods must be executed through the public interface of the class. If you have multiple implementations of the same interface, I would write test classes for each implementation.



+4


source


I think you need to split test windows.

First, you test a class that calls various interface implementations. This means that you are testing public methods.

After that, you test the interface implementation classes in another test folder. They can be called a reflection method.

0


source


I found an interesting article on how to test private methods using JUNIT at http://www.artima.com/suiterunner/privateP.html

So, my guess is that we prefer to test private methods indirectly by testing public methods. Only in exceptional circumstances should we think about testing private methods.

0


source







All Articles