JMockit : How to avoid code from superclasses' constructors - java

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.

Related

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...

Junit protected method

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.

Having helper methods in junit class

I want to unit test a class, Class A, but it has a dependency on another class that uses a user session method. The method that I want to test does not involve user session. Can I make helper method in Class A that would replicate the behavior of the Class B method that I need?
I know it's not clear, let's dig some code to get clear understanding....
public void testDetails() throws Exception
{
//Some logic that generates DetailsTOList
saveDetailsHelper(DetailsTOList);
int detailsSize = getDetailsSize();
assertNotNull(detailsSize);
}
Now getDetailsSize() get size information from a database. Class B has this method, but I cannot create an object of Class B and test this method since Class B gets session information from User, and I can set session information from JUnit class.
I have created saveDetailsHelper method that replicates behavior of Class B - saveDetails() method, and am calling that in testDetails() method as shown above.
My question:
can we have helper methods in junit class?
What is best approach to deal with this situation?
JUnit classes function like every other class in java; you're welcome to have helper functions. The only thing that determines whether other functions will be run is (depending on the version of junit) whether or not there is an annotation instructing the harness to run it as a test.
However, this problem is precisely why you should design your classes carefully. If Class B calls out to a database for information, this is a great opportunity to compartmentalize that functionality. You don't clarify 'dependency' (are you extending?), but if Class B is a component of Class A, you can create a whole stub class that is a stand in for Class B, and returns hardcoded (or otherwise coded) data specifically for the testing of class A. As long as the signature of the Class B proxy is the same, you can have confidence Class A works.
It is often useful to make these inner classes of your test class, to keep things from getting too messy in your workspace.
public class testA {
#Test
public void testDetails {
ClassA a = new ClassA();
a.setDependency(new StubClassB());
//run your test
}
private class StubClassB() extends ClassB {
public boolean saveDetails() {
//return fake information;
}
}
}
Helper methods will not have the #Testcase annotation. You would write the test code just like any other code, but would include only the relevant methods for testing, and validate only relevant portions of that test method.
You can put the helper method in the test class, omit the Testcase annotation and call it where needed (ad hoc per method or in your setup if it's needed for all tests). But probably a better solution is to use something like JMock to represent Class B and give back desired results.

AbstractFactory with a twist

I am stuck with a programming problem:
I have two Java projects, in my Eclipse IDE: ProjectA, and ProjectB.
ProjectB references ProjectA
I have declared a class in ProjectA: ClassA, and one in ProjectB: ClassB, such that:
public class ClassA{
public static Object foo(){
//blah
}
}
public class ClassB extends ClassA{
public static Object foo(){
//blah
}
}
I also have a class called ClientClass, in ProjectA. This ClientClass earlier used to create an instance of ClassA and use it. But now, based on an environment setting, the ClientClass should be provided the option to use ClassA or ClassB.
This seemed to be a problem for the AbstractFactory pattern, or so I thought.
I need to create a Factory that provides access to ClassA or ClassB. ClientClass should not be aware that it is ClassA or ClassB. This requires me to create an interface for ClassA and ClassB.
Issues I ran into:
ClientClass cannot refer to ClassB directly (no import statements / or new invocation), because ClassB is in a different project. This may be an Eclipse IDE restriction, but it also makes sense to me when viewing these two projects as jar files. A cyclic relationship is avoidable.
I cannot create a Factory interface and a common interface for ClassA & ClassB, and then via the AbstractFactory pattern provide a ClassAFactory or a ClassBFactory. This is because the methods to be invoked on ClassA and ClassB are static ones. The methods on these classes would need to be present on the interface. But then, in Java, one can't have an "abstract static" modifier
Can anyone suggest an elegant solution for this problem?
Well, there are a number of problems here. For starters, and this is the biggest one, this isn't going to work because you can't override static methods in Java. The goal, I think, of what you're saying is to be able to substitute, at run time, ClassA for ClassB or B or A or whatever, depending on some parameters. In order to do that, you need to be able to take advantage of dynamic dispatch (or, simply put, virtual methods) that would allow the runtime system to select the memory address of the method to be executed at run time. This isn't possible with static methods. You need to make the methods nonstatic for this to work. You don't have to specifically design a Java Interface but when you extend ClassA with ClassB, you'll be able to treat your objects as if they are simply a ClassA object.
All of that said, if you remove the static modifiers from the methods and make them nonstatic, then you could use ClassB in project A without having any import statements what-so-ever in the client class you're talking about. However, somewhere in project A, somebody is going to need to be aware of ClassB in order to instantiate it. That is, of course, unless you want to do some runtime binding stuff and load the class dynamically using a string. Does that make sense?
Firs problem: Your Class B and Class A's foo method is static. Hence nothing is being overriden. You should not make them static if you intend to override foo in ClassB.
The second problem here is that upstream needs to be aware of the downstream. That is just wrong isn't it?
The question of whether this is an abstract factor pattern or not is besides the point. Design patterns just make code follow a known structure. It is not an end in itself.
For now, why is it that your ClientClass in Project A needs to know about ClientB?
As for the factory, your factory needs to be in Project B and it can be something like:
class Factory {
public static ClassA createTheRightOne(EnvironmentSettings settings) { //do the right thing }
}
once you fix the static modifier
Pavan

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