Write own dependency injection - java

we are developing an application. The application will be deployed in a proprietary event processing engine. We are not supposed to use any api such as spring core for DI. There are not proprietary DI frameworks yet. So the idea is to write one and a simple one.
Can any one please provide some inputs.
My idea is to write a factory class which has static methods in it. The static methods will return instances of the classes we want. For now we only want a single instance. I am assuming the below kind of code
public final class MyFactory {
private static ClassA classA = new ClassA();
private static ClassB classB = new ClassB();
private MyFactory() {
throw new CustomException("Cannot create instance");
}
public static ClassA getClassAInstance() {
return classA;
}
public static ClassB getClassBInstance() {
return classB;
}
}
Later I will use it like this
public class SomeRandomClass {
private ClassA classA = MyFactory.getClassAInstance();
}
Other thing I see is I need not test ClassA and ClassB. Testing SomeRandomClass will cover ClassA and ClassB. Because static content is always loaded first. So while testing SomeRandomClass I always have ClassA instance in it. So writing a junit on some method in SomeRandomClass will invoke methods in ClassA. Is this good?
Is it the right way I am doing? Can I improve it even?

For starters, the factory API shouldn't reference the concrete class implementations directly like that. It kind of defeats the purpose. You won't be able to change the concrete classes without recompiling and you won't be able to do things like stubbing out interfaces for testing and development.
Then, assuming you want singletons (which is not how your example is written), you'll need to make sure your factory methods are thread safe in how they produce the singletons.
You should at a minimum have your factory return true singleton instances of interfaces. Then, you could implement some kind of configuration system and use the Java reflection API to determine which concrete classes should be created at runtime. This will also enable you to do things like stub out the interfaces for testing or development.
This isn't really DI. There's a lot more to it and it has benefits in readability/writability/configurability/maintainability that go far beyond what a factory can provide. I'm not sure why using Spring would be a problem in proprietary software. AFAIK Spring's license doesn't force code to be open source or free...

Related

How to handle 3rd Party Dependencies while Unit Testing

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.

How to create class that provides implementations of some interfaces

There is some interfaces in my app and I want to create singleton class, that provides implementations of them. Like so:
public class Singleton{
//singleton's stuff
private Interface1 interface1Impl;
private Interface2 interface2Impl;
public Interface1 getInterface1(){
return interface1Impl;
}
public Interface2 getInterface2(){
return interface2Impl;
}
}
What I'm looking for - provide same interface implementation for each class in app. With this way everything works fine, but is it a good way to achieve this?
Yes, it looks much like a Factory (or maybe Service Locator is more suitable in your case).
Factory is almost always a better idea than a Singleton. For instance, a Factory can work as a Singleton when you need it (lazy initialization, caching), and you can alter this behavior when you need something else (for testing, thread safety, etc).
It looks to me like you could be implementing dependency injection, if that's the case Google Guice is a great library for you to use.

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

mocking a singleton class

I recently read that making a class singleton makes it impossible to mock the objects of the class, which makes it difficult to test its clients. I could not immediately understand the underlying reason. Can someone please explain what makes it impossible to mock a singleton class? Also, are there any more problems associated with making a class singleton?
Of course, I could write something like don't use singleton, they are evil, use Guice/Spring/whatever but first, this wouldn't answer your question and second, you sometimes have to deal with singleton, when using legacy code for example.
So, let's not discuss the good or bad about singleton (there is another question for this) but let's see how to handle them during testing. First, let's look at a common implementation of the singleton:
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
public String getFoo() {
return "bar";
}
}
There are two testing problems here:
The constructor is private so we can't extend it (and we can't control the creation of instances in tests but, well, that's the point of singletons).
The getInstance is static so it's hard to inject a fake instead of the singleton object in the code using the singleton.
For mocking frameworks based on inheritance and polymorphism, both points are obviously big issues. If you have the control of the code, one option is to make your singleton "more testable" by adding a setter allowing to tweak the internal field as described in Learn to Stop Worrying and Love the Singleton (you don't even need a mocking framework in that case). If you don't, modern mocking frameworks based on interception and AOP concepts allow to overcome the previously mentioned problems.
For example, Mocking Static Method Calls shows how to mock a Singleton using JMockit Expectations.
Another option would be to use PowerMock, an extension to Mockito or JMock which allows to mock stuff normally not mock-able like static, final, private or constructor methods. Also you can access the internals of a class.
The best way to mock a singleton is not to use them at all, or at least not in the traditional sense. A few practices you might want to look up are:
programming to interfaces
dependency injection
inversion of control
So rather than having a single you access like this:
Singleton.getInstance().doSometing();
... define your "singleton" as an interface and have something else manage it's lifecycle and inject it where you need it, for instance as a private instance variable:
#Inject private Singleton mySingleton;
Then when you are unit testing the class/components/etc which depend on the singleton you can easily inject a mock version of it.
Most dependency injection containers will let you mark up a component as 'singleton', but it's up to the container to manage that.
Using the above practices makes it much easier to unit test your code and lets you focus on your functional logic instead of wiring logic. It also means your code really starts to become truly Object Oriented, as any use of static methods (including constructors) is debatably procedural. Thus your components start to also become truly reusable.
Check out Google Guice as a starter for 10:
http://code.google.com/p/google-guice/
You could also look at Spring and/or OSGi which can do this kind of thing. There's plenty of IOC / DI stuff out there. :)
A Singleton, by definition, has exactly one instance. Hence its creation is strictly controlled by the class itself. Typically it is a concrete class, not an interface, and due to its private constructor it is not subclassable. Moreover, it is found actively by its clients (by calling Singleton.getInstance() or an equivalent), so you can't easily use e.g. Dependency Injection to replace its "real" instance with a mock instance:
class Singleton {
private static final myInstance = new Singleton();
public static Singleton getInstance () { return myInstance; }
private Singleton() { ... }
// public methods
}
class Client {
public doSomething() {
Singleton singleton = Singleton.getInstance();
// use the singleton
}
}
For mocks, you would ideally need an interface which can be freely subclassed, and whose concrete implementation is provided to its client(s) by dependency injection.
You can relax the Singleton implementation to make it testable by
providing an interface which can be implemented by a mock subclass as well as the "real" one
adding a setInstance method to allow replacing the instance in unit tests
Example:
interface Singleton {
private static final myInstance;
public static Singleton getInstance() { return myInstance; }
public static void setInstance(Singleton newInstance) { myInstance = newInstance; }
// public method declarations
}
// Used in production
class RealSingleton implements Singleton {
// public methods
}
// Used in unit tests
class FakeSingleton implements Singleton {
// public methods
}
class ClientTest {
private Singleton testSingleton = new FakeSingleton();
#Test
public void test() {
Singleton.setSingleton(testSingleton);
client.doSomething();
// ...
}
}
As you see, you can only make your Singleton-using code unit testable by compromising the "cleanness" of the Singleton. In the end, it is best not to use it at all if you can avoid it.
Update: And here is the obligatory reference to Working Effectively With Legacy Code by Michael Feathers.
It very much depends on the singleton implementation. But it mostly because it has a private constructor and hence you can't extend it. But you have the following option
make an interface - SingletonInterface
make your singleton class implement that interface
let Singleton.getInstance() return SingletonInterface
provide a mock implementation of SingletonInterface in your tests
set it in the private static field on Singleton using reflection.
But you'd better avoid singletons (which represent a global state). This lecture explains some important design concepts from testability point of view.
It's not that the Singleton pattern is itself pure evil, but that is massively overused even in situations where it is inapproriate. Many developers think "Oh, I'll probably only ever need one of these so let's make it a singleton". In fact you should be thinking "I'll probably only ever need one of these, so let's construct one at the start of my program and pass references where it is needed."
The first problem with singleton and testing is not so much because of the singleton but due to laziness. Because of the convenience of getting a singleton, the dependency on the singleton object is often embedded directly into the methods which makes it very difficult to change the singleton to another object with the same interface but with a different implementation (for example, a mock object).
Instead of:
void foo() {
Bar bar = Bar.getInstance();
// etc...
}
prefer:
void foo(IBar bar) {
// etc...
}
Now you can test function foo with a mocked bar object which you can control. You've removed the dependency so that you can test foo without testing bar.
The other problem with singletons and testing is when testing the singleton itself. A singleton is (by design) very difficult to reconstruct, so for example you can only test the singleton contructor once. It's also possible that the single instance of Bar retains state between tests, causing success or failure depending on the order that the tests are run.
There is a way to mock Singleton. Use powermock to mock static method and use Whitebox to invoke constructor YourClass mockHelper = Whitebox
.invokeConstructor(YourClass.class);
Whitebox.setInternalState(mockHelper, "yourdata",mockedData);
PowerMockito.mockStatic(YourClass.class);
Mockito.when(YourClass.getInstance()).thenReturn(mockHelper);
What is happening is that the Singleton byte code is changing in run-time .
enjoy

How can I easily mock out a static method in Java (jUnit4)

How do I easily mock out a static method in Java?
I'm using Spring 2.5 and JUnit 4.4
#Service
public class SomeServiceImpl implements SomeService {
public Object doSomething() {
Logger.getLogger(this.class); //a static method invoked.
// ...
}
}
I don't control the static method that my service needs to invoke so I cannot refactor it to be more unit-testable. I've used the Log4J Logger as an example, but the real static method is similar. It is not an option to change the static method.
Doing Grails work, I'm used to using something like:
def mockedControl = mockFor(Logger)
mockControl.demand.static.getLogger{Class clazz-> … }
…
mockControl.verify()
How do I do something similar in Java?
Do you mean you can't control the calling code? Because if you control the calls to the static method but not the implementation itself, you can easily make that testable. Create a dependency interface with a single method with the same signature as the static method. Your production implementation will just call through to the static method, but anything which currently calls the static method will call via the interface instead.
You can then mock out that interface in the normal way.
The JMockit framework promises to allow mocking of static methods.
https://jmockit.dev.java.net/
In fact, it makes some fairly bold claims, including that static methods are a perfectly valid design choice and their use should not be restricted because of the inadequacy of testing frameworks.
Regardless of whether or not such claims are justifiable, the JMockit framework itself is pretty interesting, although I've yet to try it myself.
PowerMock has this ability. It can also mock instantiations of objects inside the class under test. If your tested method calls new Foo(), you can create a mock object for that Foo and replace it in the method you are testing.
Things like suppressing constructors and static initializers are also possible. All of these things are considered untestable code and thus not recommended to do but if you have legacy code, changing it is not always an option. If you are in that position, PowerMock can help you.
public interface LoggerWrapper {
public Logger getLogger(Class<?> c);
}
public class RealLoggerWrapper implements LoggerWrapper {
public Logger getLogger(Class<?> c) {return Logger.getLogger(c);}
}
public class MockLoggerWrapper implements LoggerWrapper {
public Logger getLogger(Class<?> c) {return somethingElse;}
}
As another answer above stated, JMockit can mock static methods (and anything else, as well).
It even has direct support for logging frameworks. For example, you could write:
#UsingMocksAndStubs(Log4jMocks.class)
public class SomeServiceTest
{
// All test methods in this class will have any calls
// to the Log4J API automatically stubbed out.
}
Support for JUnit 4.4 was dropped, however. JUnit 3.8, JUnit 4.5+ and TestNG 5.8+ are supported.
That's one of the reason static methods are bad.
We re-architect ed most of our factories to have setters as well so that we could set mock objects into them. In fact, we came up with something close to dependency injection where a single method acted as a factory for all our singletons.
In your case, adding a Logger.setLogger() method (and storing that value) could work. If you have to you could extend the logger class and shadow the getLogger method with your own as well.
You could use AspectJ to intercept the static method call and do something useful for your test.
Basically, There isn't an easy way to do this in Java + Spring 2.5 & JUnit 4.4 at the moment.
Although it is possible to refactor, and abstract away the static call, Refactoring the code isn't the solution that I was looking for.
JMockit looked like it would work, but is incompatibile with Spring 2.5 and JUnit 4.4.

Categories