Junit protected method - java

I'm wondering about a nice way to deal with a protected method in Junit.
Assuming I want to test a class called A which has a protected member and constructor.
I understood that in order to test the class A I should write another class called ATest which might extend TestCase ( this should be mandatory in Junit3 ). Because I want to test a protected method and because A has a protected constructor, my test class ATest should also extend the class A where that method is implemented in order to be able to create that class and to access to the method.
could be a double inheritance from both classes a nice solution?
P.S I've already Known that in Junit 4 the inheritance from the TestCase might be avoided.

To gain access to A's protected members, you can just put A and ATest in the same package.

Java doesn't allow multiple inheritance of implementation. You can implement multiple interfaces.
I would prefer using reflection to get at methods for testing that I don't want clients to know about. Works for private methods, too.

Related

what is the advantage of using #VisibleForTesting? [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
Who has a solution for that common need.
I have a class in my application.
some methods are public, as they are part of the api,
and some are private, as they for internal use of making the internal flow more readable
now, say I want to write a unit test, or more like an integration test, which will be located in a different package, which will be allowed to call this method, BUT, I want that normal calling to this method will not be allowed if you try to call it from classes of the application itself
so, I was thinking about something like that
public class MyClass {
public void somePublicMethod() {
....
}
#PublicForTests
private void somePrivateMethod() {
....
}
}
The annotation above will mark the private method as "public for tests"
which means, that compilation and runtime will be allowed for any class which is under the test... package , while compilation and\or runtime will fail for any class which is not under the test package.
any thoughts?
is there an annotation like this?
is there a better way to do this?
it seems that the more unit tests you write, to more your inforced to break your encapsulation...
The common way is to make the private method protected or package-private and to put the unit test for this method in the same package as the class under test.
Guava has a #VisibleForTesting annotation, but it's only for documentation purposes.
If your test coverage is good on all the public method inside the tested class, the privates methods called by the public one will be automatically tested since you will assert all the possible case.
The JUnit Doc says:
Testing private methods may be an indication that those methods should be moved into another class to promote reusability.
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the aid of the PrivilegedAccessor. For details on how to use it, read this article.
Consider using interfaces to expose the API methods, using factories or DI to publish the objects so the consumers know them only by the interface. The interface describes the published API. That way you can make whatever you want public on the implementation objects and the consumers of them see only those methods exposed through the interface.
dp4j has what you need. Essentially all you have to do is add dp4j to your classpath and whenever a method annotated with #Test (JUnit's annotation) calls a method that's private it will work (dp4j will inject the required reflection at compile-time). You may also use dp4j's #TestPrivates annotation to be more explicit.
If you insist on also annotating your private methods you may use Google's #VisibleForTesting annotation.
An article on Testing Private Methods lays out some approaches to testing private code. using reflection puts extra burden on the programmer to remember if refactoring is done, the strings aren't automatically changed, but I think it's the cleanest approach.
Or you can extract this method to some strategy object. In this case you can easily test extracted class and don't make method public or some magic with reflection/bytecode.
Okay, so here we have two things that are being mixed. First thing, is when you need to mark something to be used only on test, which I agree with #JB Nizet, using the guava annotation would be good.
A different thing, is to test private methods. Why should you test private methods from the outside? I mean.. You should be able to test the object by their public methods, and at the end that its behavior. At least, that we are doing and trying to teach to junior developers, that always try to test private methods (as a good practice).
I am not aware of any such annotation, however the following may be of value: unit testing private methods
or the following: JMockit
You can't do this, since then how could you even compile your tests? The compiler won't take the annotation into account.
There are two general approaches to this
The first is to use reflection to access the methods anyway
The second is to use package-private instead of private, then have your tests in the same package (but in a different module). They will essentially be private to other code, but your tests will still be able to access them.
Of course, if you do black-box testing, you shouldn't be accessing the private members anyway.
We recently released a library that helps a lot to access private fields, methods and inner classes through reflection : BoundBox
For a class like
public class Outer {
private static class Inner {
private int foo() {return 2;}
}
}
It provides a syntax like :
Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();
The only thing you have to do to create the BoundBox class is to write #BoundBox(boundClass=Outer.class) and the BoundBoxOfOuter class will be instantly generated.
As much as I know there is no annotation like this. The best way is to use reflection as some of the others suggested. Look at this post:
How do I test a class that has private methods, fields or inner classes?
You should only watch out on testing the exception outcome of the method. For example: if u expect an IllegalArgumentException, but instead you'll get "null" (Class:java.lang.reflect.InvocationTargetException).
A colegue of mine proposed using the powermock framework for these situations, but I haven't tested it yet, so no idea what exactly it can do. Although I have used the Mockito framework that it is based upon and thats a good framework too (but I think doesn't solve the private method exception issue).
It's a great idea though having the #PublicForTests annotation.
Cheers!
I just put the test in the class itself by making it an inner class:
https://rogerkeays.com/how-to-unit-test-private-methods

Enforcing that a JUnit subclass test overrides a #BeforeClass method

I have what amounts to a lightweight test framework written as a JUnit Abstract test. What I would like to do is have the implementing subclasses each define their custom test class setup. My plan was to have the abstract superclass define an #BeforeClass method that calls into an abstract setup method that each subclass would be forced to define, but this fails as the #BeforeClass methods must be static and static methods cannot be made abstract nor can they call instance methods.
I could just assume that subclasses will do the setup by including what's required in the documentation or by throwing an IllegalStateException, but I'd really like to be able to enforce this at an interface level for a number of reasons. Can anyone think of a work around for this?
By the way, I had the same issue with making these tests parameterized (subclasses define the parameters, but #Parameters annotated methods must be static). I got around this by running with the 3rd party JUnitParams runner which allows method level parameters. Check it out here: https://github.com/Pragmatists/JUnitParams
One option is to have subclasses implement a, say, static doSetupOnce() method, and find and invoke that method reflectively from the base class #BeforeClass method. Since this needs to be a static method, its existence can only be enforced at runtime.
Another approach would be to have an abstract doSetupOnce instance method in the base class which gets invoked the first time the parent's #Before method gets invoked. This enforces the issue at compile time, but then implementors will have to be careful not to access instance fields from this method (since this is probably not what they want).
In general (and without knowing the details of your situation), I'm not very fond of either of these approaches, and would rather leave it up to implementors to declare a #BeforeClass method if needed. Locking them up in a rigid base class scheme can cause more problems than it solves. Also consider the use of JUnit rules, which often are a better choice than base classes (e.g. because they are composable). Of course you can also combine the two approaches, relying mainly on JUnit rules and additionally offering some base classes with predefined rules for convenience.
For your main question, why not make your parent class abstract and use the #Before annotation instead of #BeforeClass ? For example:
public abstract class TestParent {
#Before
public void setup() {
doSetup();
}
protected abstract void doSetup();
// other stuff...
}
public class RealTest extends TestParent {
protected void doSetup() {
// custom setup
}
// custom tests...
}
This will force the subclasses to redefine the doSetup() method without using static methods.
This may be out of scope or overkill, but I think it's worth mentioning since they're not that different. So I'm taking a leap of faith and suggest that you could try TestNG because methods annotated with #BeforeClass do not have to be static, nor do those annotated with #Parameters.
You can read about the differences between the 2 frameworks here and it looks like they also have support for migrating JUnit tests to TestNG
I don't think it is possible to do this in a clean OO way. Not only is #BeforeClass a static method, but JUnit will call the parent's #BeforeClass before the child's #BeforeClass.
Anyway you try to do this must necessarily expose the parent class's internal static state so a child class can set the parent's fields, breaking encapsulation.
I think the best way is to to use #Before, but also have a static flag that sets if the method has been called before, that way at least you can short circuit and only do the initialization for the first call...

JMockit : How to avoid code from superclasses' constructors

I need to test a class SportCar, which extends Car. The problem is that when I create my object under test
SportCar car = new SportCar();
it will also call the constructor from parent classes, for example, Car(). Those constructors do a lot of things, have a lot of environment dependencies and need a lot of configuration files I don't have, so I would like to create an instance of SportCar without calling inherited constructors.
The only solution I know for this is to create a Mockup for Car in which I overwrite constructor ($init) and static block ($clinit). But now my problem is, what happens if there are many classes in my hierarchy (SportCar extends Car that extends A that extends B that extends C...) and I want to avoid all the constructors? Should I create Mocks for ALL the previous classes?
class A extends B{
public A(){
// Plenty of things to avoid during tests
}
}
class Car extends A{
public Car(){
// Plenty of things to avoid during tests
}
}
class SportCar extends Car(){
}
If you are using jmockit, you do not have to do anything at all, as all the superclass constructors are mocked by default. In you unit test method you can just do:
public void testMockedStuff(#Mocked final ClassToBeMocked instance) {
to have evrything mocked away for you. You do not even have to create instances yourself.
Then you can modify annotation parameters to exclude methods you are teting from mocking.
Create a protected "do nothing" constructor in Car and have a protected constructor in SportsCar that calls it and call that from your test class, which can see that constructor btw - it has the privileges to do so.
This could be considered a slight stretch of the "design for test" pattern.
You can suppress the parent constructor using PowerMock
suppress(constructor(EvilParent.class));
However, if you have to do a lot of unit tests it may be worth figuring out how to fake out the enironment as well. Or convince other developers to let you do a little refactoring to allow service injection at least.

Should I create static method or abstract superclass

I am trying to refactor a project in which there are same methods which are spread across various classes. To reduce code duplication, should I move the common code to an abstract superclass or should I put it in a static method in a utility class?
EDIT
Some of the methods are for generic stuff which I believe can be made static. While there are others which refer to attributes of the class, in which case I think it makes more sense to make it as an abstract super class.
Well, I follow a rule: Don't use base class to remove code duplication, use utility class.
For inheritance, ask question to yourself: Does Is-A relationship exist?
Another rule, which most of the times is correct, is: Prefer composition over inheritance
using static utility class is NOT true composition but it can be called a derivation of it.
Apply these rules to your secenrios and take a decision keeping in mind maintanence and scalability. However it will be good if you could add more details to your quesiton.
It depends on what your code is doing. Are they utility methods? Are they specific/specialized class methods? Is this a heavy multithreaded application?
Keep in mind that if you make them static and your application is multithreaded, you will have to protect them w locks. This, in turn, reduces concurrency. In this case, depending on how many threads call that same piece of code, you might consider moving it (the code) to a super class.
Another point to consider may be the type of work these functions do. If that is scattered, you should create a facade / helper / util class with static methods.
As others have mentioned the answer to this depends on the context of the problem and the duplicated code.
Some things to consider
Does the duplicated code mutate the instance of the object. In this case a protected method in a common abstract class
Instead of Static utility class consider a singleton, Static methods can be problematic for pure unit testing although testing frameworks are getting better at this.
Inheritance can be tricky to get right, think about if these objects from the different classes are really related and require some OO re-factoring ? or are they disjoint pieces of domain logic that happen to require similar bits of code.
If it does not use any class members you might do it static!
But you should do it in a abstract class or mother class
If the methods use many fields or methods of the class they should not be static.
If they are something that a subclass might want to modify they should not be static.
If the methods should be part of an Interface they cannot be static.
Otherwise it's your call and you will probably change your mind later. :-)
At first glance, I would say that it would be better to make the common code as a public static method in a public class. This will make the method useful to any class just by using
UtilityClassName.methodName();
This is better then making it a concrete method in an abstract super-class because then you will always need to extend this super-class in all the classes where you want to use this one single method.
But now, as you said that the method's behavior depends on some variables. Now, if it depends on the instance variables of different classes, then better add this method in an interface and let all your classes implement this interface and have their own implementation of the same.
But again if these variables are constant values, then have these constant values in an interface. Implement these interface in your utility class. And again make it a static method in that utility class which will directly use these constants.
For e.g. Consider foll. common code of returning area of a circle.
public interface TwoDimensional{
double PI = 3.14;
}
public class MyUtility implements TwoDimensional{
public static double getCircleArea(double radius){
return PI*radius*radius;
}
}
Here, you can see that method getCircleArea() depends on the radius which will be different for different classes but still I can pass this value to the static method of myUtility class.

How to unit test abstract classes: extend with stubs?

I was wondering how to unit test abstract classes, and classes that extend abstract classes.
Should I test the abstract class by extending it, stubbing out the abstract methods, and then test all the concrete methods? Then only test the methods I override, and test the abstract methods in the unit tests for objects that extend my abstract class?
Should I have an abstract test case that can be used to test the methods of the abstract class, and extend this class in my test case for objects that extend the abstract class?
Note that my abstract class has some concrete methods.
There are two ways in which abstract base classes are used.
You are specializing your abstract object, but all clients will use the derived class through its base interface.
You are using an abstract base class to factor out duplication within objects in your design, and clients use the concrete implementations through their own interfaces.!
Solution For 1 - Strategy Pattern
If you have the first situation, then you actually have an interface defined by the virtual methods in the abstract class that your derived classes are implementing.
You should consider making this a real interface, changing your abstract class to be concrete, and take an instance of this interface in its constructor. Your derived classes then become implementations of this new interface.
This means you can now test your previously abstract class using a mock instance of the new interface, and each new implementation through the now public interface. Everything is simple and testable.
Solution For 2
If you have the second situation, then your abstract class is working as a helper class.
Take a look at the functionality it contains. See if any of it can be pushed onto the objects that are being manipulated to minimize this duplication. If you still have anything left, look at making it a helper class that your concrete implementation take in their constructor and remove their base class.
This again leads to concrete classes that are simple and easily testable.
As a Rule
Favor complex network of simple objects over a simple network of complex objects.
The key to extensible testable code is small building blocks and independent wiring.
Updated : How to handle mixtures of both?
It is possible to have a base class performing both of these roles... ie: it has a public interface, and has protected helper methods. If this is the case, then you can factor out the helper methods into one class (scenario2) and convert the inheritance tree into a strategy pattern.
If you find you have some methods your base class implements directly and other are virtual, then you can still convert the inheritance tree into a strategy pattern, but I would also take it as a good indicator that the responsibilities are not correctly aligned, and may need refactoring.
Update 2 : Abstract Classes as a stepping stone (2014/06/12)
I had a situation the other day where I used abstract, so I'd like to explore why.
We have a standard format for our configuration files. This particular tool has 3 configuration files all in that format. I wanted a strongly typed class for each setting file so, through dependency injection, a class could ask for the settings it cared about.
I implemented this by having an abstract base class that knows how to parse the settings files formats and derived classes that exposed those same methods, but encapsulated the location of the settings file.
I could have written a "SettingsFileParser" that the 3 classes wrapped, and then delegated through to the base class to expose the data access methods. I chose not to do this yet as it would lead to 3 derived classes with more delegation code in them than anything else.
However... as this code evolves and the consumers of each of these settings classes become clearer. Each settings users will ask for some settings and transform them in some way (as settings are text they may wrap them in objects of convert them to numbers etc.). As this happens I will start to extract this logic into data manipulation methods and push them back onto the strongly typed settings classes. This will lead to a higher level interface for each set of settings, that is eventually no longer aware it's dealing with 'settings'.
At this point the strongly typed settings classes will no longer need the "getter" methods that expose the underlying 'settings' implementation.
At that point I would no longer want their public interface to include the settings accessor methods; so I will change this class to encapsulate a settings parser class instead of derive from it.
The Abstract class is therefore: a way for me to avoid delegation code at the moment, and a marker in the code to remind me to change the design later. I may never get to it, so it may live a good while... only the code can tell.
I find this to be true with any rule... like "no static methods" or "no private methods". They indicate a smell in the code... and that's good. It keeps you looking for the abstraction that you have missed... and lets you carry on providing value to your customer in the mean time.
I imagine rules like this one defining a landscape, where maintainable code lives in the valleys. As you add new behaviour, it's like rain landing on your code. Initially you put it wherever it lands.. then you refactor to allow the forces of good design to push the behaviour around until it all ends up in the valleys.
Write a Mock object and use them just for testing. They usually are very very very minimal (inherit from the abstract class) and not more.Then, in your Unit Test you can call the abstract method you want to test.
You should test abstract class that contain some logic like all other classes you have.
What I do for abstract classes and interfaces is the following: I write a test, that uses the object as it is concrete. But the variable of type X (X is the abstract class) is not set in the test. This test-class is not added to the test-suite, but subclasses of it, that have a setup-method that set the variable to a concrete implementation of X. That way I don't duplicate the test-code. The subclasses of the not used test can add more test-methods if needed.
To make an unit test specifically on the abstract class, you should derive it for testing purpose, test base.method() results and intended behaviour when inheriting.
You test a method by calling it so test an abstract class by implementing it...
If your abstract class contains concrete functionality that has business value, then I will usually test it directly by creating a test double that stubs out the abstract data, or by using a mocking framework to do this for me. Which one I choose depends a lot on whether I need to write test-specific implementations of the abstract methods or not.
The most common scenario in which I need to do this is when I'm using the Template Method pattern, such as when I'm building some sort of extensible framework that will be used by a 3rd party. In this case, the abstract class is what defines the algorithm that I want to test, so it makes more sense to test the abstract base than a specific implementation.
However, I think it's important that these tests should focus on the concrete implementations of real business logic only; you shouldn't unit test implementation details of the abstract class because you'll end up with brittle tests.
one way is to write an abstract test case that corresponds to your abstract class, then write concrete test cases that subclass your abstract test case. do this for each concrete subclass of your original abstract class (i.e. your test case hierarchy mirrors your class hierarchy). see Test an interface in the junit recipies book: http://safari.informit.com/9781932394238/ch02lev1sec6. https://www.manning.com/books/junit-recipes or https://www.amazon.com/JUnit-Recipes-Practical-Methods-Programmer/dp/1932394230 if you don't have a safari account.
also see Testcase Superclass in xUnit patterns: http://xunitpatterns.com/Testcase%20Superclass.html
I would argue against "abstract" tests. I think a test is a concrete idea and doesn't have an abstraction. If you have common elements, put them in helper methods or classes for everyone to use.
As for testing an abstract test class, make sure you ask yourself what it is you're testing. There are several approaches, and you should find out what works in your scenario. Are you trying to test out a new method in your subclass? Then have your tests only interact with that method. Are you testing the methods in your base class? Then probably have a separate fixture only for that class, and test each method individually with as many tests as necessary.
This is the pattern I usually follow when setting up a harness for testing an abstract class:
public abstract class MyBase{
/*...*/
public abstract void VoidMethod(object param1);
public abstract object MethodWithReturn(object param1);
/*,,,*/
}
And the version I use under test:
public class MyBaseHarness : MyBase{
/*...*/
public Action<object> VoidMethodFunction;
public override void VoidMethod(object param1){
VoidMethodFunction(param1);
}
public Func<object, object> MethodWithReturnFunction;
public override object MethodWithReturn(object param1){
return MethodWihtReturnFunction(param1);
}
/*,,,*/
}
If the abstract methods are called when I don't expect it, the tests fail. When arranging the tests, I can easily stub out the abstract methods with lambdas that perform asserts, throw exceptions, return different values, etc.
If the concrete methods invoke any of the abstract methods that strategy won't work, and you'd want to test each child class behavior separately. Otherwise, extending it and stubbing the abstract methods as you've described should be fine, again provided the abstract class concrete methods are decoupled from child classes.
I suppose you could want to test the base functionality of an abstract class... But you'd probably be best off by extending the class without overriding any methods, and make minimum-effort mocking for the abstract methods.
One of the main motivations for using an abstract class is to enable polymorphism within your application -- i.e: you can substitute a different version at runtime. In fact, this is very much the same thing as using an interface except the abstract class provides some common plumbing, often referred to as a Template pattern.
From a unit testing perspective, there are two things to consider:
Interaction of your abstract class with it related classes. Using a mock testing framework is ideal for this scenario as it shows that your abstract class plays well with others.
Functionality of derived classes. If you have custom logic that you've written for your derived classes, you should test those classes in isolation.
edit: RhinoMocks is an awesome mock testing framework that can generate mock objects at runtime by dynamically deriving from your class. This approach can save you countless hours of hand-coding derived classes.
First if abstract class contained some concrete method i think you should do this considered this example
public abstract class A
{
public boolean method 1
{
// concrete method which we have to test.
}
}
class B extends class A
{
#override
public boolean method 1
{
// override same method as above.
}
}
class Test_A
{
private static B b; // reference object of the class B
#Before
public void init()
{
b = new B ();
}
#Test
public void Test_method 1
{
b.method 1; // use some assertion statements.
}
}
If an abstract class is appropriate for your implementation, test (as suggested above) a derived concrete class. Your assumptions are correct.
To avoid future confusion, be aware that this concrete test class is not a mock, but a fake.
In strict terms, a mock is defined by the following characteristics:
A mock is used in place of each and every dependency of the subject class being tested.
A mock is a pseudo-implementation of an interface (you may recall that as a general rule, dependencies should be declared as interfaces; testability is one primary reason for this)
Behaviors of the mock's interface members -- whether methods or properties
-- are supplied at test-time (again, by use of a mocking framework). This way, you avoid coupling of the implementation being tested with the implementation of its dependencies (which should all have their own discrete tests).
Following #patrick-desjardins answer, I implemented abstract and it's implementation class along with #Test as follows:
Abstract class - ABC.java
import java.util.ArrayList;
import java.util.List;
public abstract class ABC {
abstract String sayHello();
public List<String> getList() {
final List<String> defaultList = new ArrayList<>();
defaultList.add("abstract class");
return defaultList;
}
}
As Abstract classes cannot be instantiated, but they can be subclassed, concrete class DEF.java, is as follows:
public class DEF extends ABC {
#Override
public String sayHello() {
return "Hello!";
}
}
#Test class to test both abstract as well as non-abstract method:
import org.junit.Before;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.contains;
import java.util.Collection;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import org.junit.Test;
public class DEFTest {
private DEF def;
#Before
public void setup() {
def = new DEF();
}
#Test
public void add(){
String result = def.sayHello();
assertThat(result, is(equalTo("Hello!")));
}
#Test
public void getList(){
List<String> result = def.getList();
assertThat((Collection<String>) result, is(not(empty())));
assertThat(result, contains("abstract class"));
}
}

Categories