How to handle 3rd Party Dependencies while Unit Testing - java

I am developing a plugin for a proprietary application.
The specification essentially is that I have functions with specified names. When installed, the parent application will call the functions in my plugin - passing in various parameters.
I want to unit test my plugin, but I don't have access to the source of the parent application. I can't instantiate the required parameters to test my function.
In this particular case, my parameter is an object with two data elements I access and a logging function that I access. Mocking up a sample wouldn't be too difficult, but I'm faced with a bit of a dilemma...
public PerSpecResponseObject myPluginFunction(ThirdPartyObject iUseThis){
...
}
I can't pass my own object into "myPluginFunction", I need something of the type ThirdPartyObject. If I define an interface, I don't have access to the ThirdPartyObject to specify that it implements the interface. I can't subclass ThirdPartyObject and use a generic parameter (<? extends ThirdPartyObject>), because my plugin is implementing an interface, so my parameter types are restricted. I looked into Mocking and while interesting, it didn't seem applicable for my situation.
What solutions exist for this situation?

It would indeed be best to be able to construct a real ThirdPartyObject.
Since you need to refer to this class, you have at least some 3rd party library on your class path that contains this class.
Are you sure there's no way to construct it, e.g. using a factory which is also in the library? Or by constructing another object and calling a method that will call your plugin with a ThirdPartyObject instance?
While this is sometimes called integration testing (since you're testing the integration with the main application), it can also be considured unit testing in the classical sense as long as the test doesn't e.g. put data in a database or does anything else that could potentially influence other tests.
If the above isn't possible, you may resort to mocking out ThirdPartyObject e.g. using Mockito. Try to make sure you your test code isn't coupled to your implementation any more than it needs to be. Some people think they need to mock out all dependencies of a class and then verify all method calls to those dependencies. They're introducing a lot of strong coupling and redundancy.
Concerning the 2 problems you mentioned, there are ways around both:
1) You say you can't make ThirdPartyObject implement an interface. That's true, but you can write an adapter that implements this interface and delegates to a ThirdPartyObject. Then the method called by the main application would simply delegate to the actual plugin method implementation that uses this interface.
Example (suppose ThirdPartyObject has a single method void thirdPartyMethodCall():
public interface InterfaceForThirdPartyObject {
void thirdPartyMethodCall();
}
public class ThirdPartyObjectAdapter implements InterfaceForThirdPartyObject {
private final ThirdPartyObject delegate;
public ThirdPartyObjectAdapter(ThirdPartyObject delegate) {
this.delegate = delegate;
}
public void thirdPartyMethodCall() {
delegate.thirdPartyMethodCall();
}
}
// your actual plugin implementation, not directly exposed to the main app
public class MyPlugin {
public PerSpecResponseObject myPluginFunction(InterfaceForThirdPartyObject iUseThis){
// this will contain your actual logic that you want to test
}
}
// this is the plugin as exposed to the main app
public class MyPluginAdapter implements PluginInterface {
private final MyPlugin delegate = new MyPlugin();
// this is called by the main application
public PerSpecResponseObject myPluginFunction(ThirdPartyObject iUseThis) {
delegate.myPluginFunction(new ThirdPartyObjectAdapter(iUseThis));
}
}
2) You say you can't subclass ThirdPartyObject because the plugin implements an interface that has a ThirdPartyObject as method argument instead of ? extends ThirdPartyObject. I don't see why that would be a problem: a method that takes a ThirdPartyObject as parameter will happily take instances of any subclass of ThirdPartyObject.

If you had access to the source of the parent application, you wouldn't be unit-testing, but integration-testing.
You can mock ThirdPartyObject. In fact, you have to mock ThirdPartyObject if what you want to do is unit-testing.
Just create a class with the same FQN as ThirdPartyObject, but keep it in your test folders so it doesn't get distributed.
This is the simplest I can think of.

Related

How are subclasses of an interface get called

This is a question that has been bothering me for a while.
In frameworks like Jersey we have interface(s) that we can subclass to add some functionality to our program. for example to add request filtering in a RESt application we can implement ContainerRequestFilter then Voila we got authentication.
My question is how does the framework/library know that we have subclass one of its interfaces?
as per my understanding you can't instantiate an interface, only its subclass such as:
public interface Greeter{
void sayHi();
}
public class SpanishGreeter implements Greeter{
#override
void sayHi(){
System.out.println("Hola");
}
}
public class Controller{
public void main(String[] args){
//We must know the name of subclass to instantiate?
Greeter spanishG = new SpanishGreeter();
}
}
What you're looking for is classpath scanning.
This isn't a trivial task, and it's pretty much what the name says: you basically need to scan the classpath and load every class you find (although the typical implementation will allow you to limit your search to certain packages and its subpackages only, to stop from things going really crazy).
There are no special tricks in the Java language that would make this task easy.
The good news is that you don't need to write it from scratch, as frameworks like Spring already have it built in, or if you want to have complete low-level control, you can use a dedicated library like Reflections.
I think instanceof keyword helps in it.
System.out.println(spanishG instanceof Greeter); // true
That happens due to Polymorphism. The code you mentioned
Greeter spanishG = new SpanishGreeter();
That has reference of parent(in you case interface). On run time it checks weather there is a child class implementing the method if yes then it calls child class behaviour. And in your class you are instantiating with child class on run time JVM knows you have provided implementation.

Have a different classpath for testing in java

I have implemented a injection functionality into my framework so I can annotate implementations of my interface BattleResolver and then let the specific class I want these implementations to be injected, decide which one it takes depending on the annotation value of type enum.
#Resolver(Conflict.ConflictType.INFANTRY_CONFLICT)
public class TestArmorResolver implements BattleResolver {
}
#Resolver(ConflictType.ARMORED_CONFLICT)
public class TestInfantryResolver implements BattleResolver {
// implementation
}
As you can see the difference between both classes is the conflict type they resolve. I have written a test which assures me that these classes are valid for injecting and that the proper class will be injected for a given conflict type.
Now I want to test the side-effects. Like having two classes resolve for the same type, which is not allowed for the framework.
The difference would simply look like this:
#Resolver(ConflictType.INFANTRY_CONFLICT)
public class TestInfantryResolverWrong implements BattleResolver {
// implementation
}
#Resolver(Conflict.ConflictType.INFANTRY_CONFLICT)
public class TestArmorResolverWrong implements BattleResolver {
}
Both having the type INFANTRY_CONFLICT. I have no way to actually tell the test to take the second two and not the first two, so I can test for wrong user behaviour.
I would like to create a second classpath or a third to store my test fixture java classes. But how to actually direct the test to these classpaths to pickup the test fixtures. And how to let the test actually have access to the classes of the main classpath?

java create a wrapper interface for another interface

The problem I am facing is as below -
I am using a 3rd party library, say Editor, which has an interface , EditorActions, with methods -
create(), edit(), delete().
I do not want to expose, EditorActions 's methods in my implementation. So my interface will have methods like -
myCreate(), myEdit(), myDelete() which in turn should call the EditorActions methods.
EditorActions is only an interface, the implementation is internal to the library.
How do I link the 2 interfaces without implementing either of them?
thanks for all your help
You can do this by exposing the methods that you want people to use in an abstract class. And then force people to implement the specific methods that you want them to.
You can then use the methods from the EditorActions interface as well as the methods that you force you implementations to implement.
public abstract class AbstractEditorActions {
private EditorActions ea;
public AbstractEditorActions(EditorActions ea) {
this.ea = ea;
}
// In this method, you can use the methods
// from the interface and from this abstract class.
// Make the method final so people don't break
// the implementation.
public final void yourExposedMethod() {
// code
this.toImplement();
ea.doMethod();
}
protected abstract toImplement();
}
Assuming you obtain an instance of EditorActions from the library you could do this:
public class FooActions implements MyEditorActions, EditorActions{
private EditorActions internal;
public FooActions(EditorActions internal){
this.internal = internal;
}
#Override
public void create(){
internal.create();
}
#Override
public void myCreate(){
// do stuff
this.create();
}
}
What this does is wrap the instance of the library object with an object that implements the same interface as well as yours. Then, you just expose the object as whatever interface you want it to be.
EditorActions a1 = new FooActions(); // a1 only shows library methods
MyEditorActions a2 = a1; // now a2 only shows your methods
How do I link the 2 interfaces without implementing either of them?
You can't. You are trying to do automatic magic here. Don't do magic. You have to implement either one of them no matter what.
Or, you'll have to implement your own reflection plumbing (or AOP somehow) to create classes on the fly. The later is no trivial manner, and typically an overkill and a red-flag of over-engineering just to avoid implementing what amounts to be a plain-old delegate.
OTH, if you only wanted to "expose" a subset of the methods provided by a third party interface A (say, for example, only the getter methods), you could almost trivially create (by good old elbow grease or a reflection library) an interface B that only exposes that subset of methods you desire.
interface DirtyThirdPartyInterface
{
StupidCrap getSomeStupidCrap();
void setStupidCrap();
}
interface MySanitizedInterface
{
StupidCrap getSomeStupidCrap();
// the setter is not part of this interface
}
Then with, say, Spring AOP or something similar or one of the several reflection libraries out there, then you could auto-generate an implementation of MySanitizedInterface as an AOP interceptor that simply proxies the call to the getter (via reflection) to the getter in the 3rd party interface.
But again, that's a lot of crap (not to mention 3rd party library dependencies) to simply avoiding what amounts to be simple hand-coding. It is rare to find a real-world case that justifies all that plumbing malarkey. If I were to run into something like that, the first thing I would think is "red flag". YMMV of course.

Java reflection: How do I override or generate methods at runtime?

It is possible in plain Java to override a method of a class
programmatically at runtime (or even create a new method)?
I want to be able to do this even if I don't know the classes at compile time.
What I mean exactly by overriding at runtime:
abstract class MyClass{
public void myMethod();
}
class Overrider extends MyClass{
#Override
public void myMethod(){}
}
class Injector{
public static void myMethod(){ // STATIC !!!
// do actual stuff
}
}
// some magic code goes here
Overrider altered = doMagic(
MyClass.class, Overrider.class, Injector.class);
Now, this invocation...
altered.myMethod();
...would call Injector.myMethod() instead of Overrider.myMethod().
Injector.myMethod() is static, because, after doing "magic"
it is invoked from different class instance (it's the Overrider),
(so we prevent it from accessing local fields).
You can use something like cglib for generating code on-the-fly
In java6 has been added the possibility to transform any already loaded class. Take a look at the changes in the java.lang.instrument package
For interfaces there is java.lang.reflect.Proxy.
For classes you'll either need a third-party library or write a fair bit of code. Generally dynamically creating classes in this way is to create mocks for testing.
There is also the instrumentation API that allows modification of classes. You can also modify classes with a custom class loader or just the class files on disk.
I wrote an article for java.net about how to transparently add logging statements to a class when it is loaded by the classloader using a java agent.
It uses the Javassist library to manipulate the byte code, including using the Javassist compiler to generate extra bytecode which is then inserted in the appropriate place, and then the resulting class is provided to the classloader.
A refined version is available with the slf4j project.
If I got it right, the main problem that concerns you is how to pass a static method delegate (like in C#), through the instance interface method.
You can check this article: A Java Programmer Looks at C# Delegates (archived), which shows you how to get a reference to your static method and invoke it. You can then create a wrapper class which accepts the static method name in its constructor, and implements your base class to invoke the static method from the instance method.

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