how to mock class which calls singleton class using junit - java

I would like to test a method from class1 which calls the singleton class getInstance:
Class ivDomain {
public String method1() {
id=Singleton.getInstance().generateId()
... code
}
}
When I do the test using Junit I am getting NullPointerException on the singleton class. How can I fix this?

Classes using statically accessed singletons are a pain to test. Change you ivDomain class to rather take the singleton instance as a parameter to it's constructor and then mock it normally. You should use a Dependency Injection framework (such as Guice) going forward to make this style of development easier.

You shouldn't have to mock Singleton; just change the code so getInstance() doesn't return a null.

The most likely reason - without examining your Singleton's code - is that it's initialization fails to load some external configuration and therefore fails.
Singletons in Automatic Unit Tests can be a problem since sometimes you like them to behave differently for the specific scenario you test (e.g. you want one scenario where generateId returns -1, another when it returns 4354353 and another when it throws a RuntimeException - just so you can see how the code that uses the Singleton works. In such cases a change of design is recommended as Singletons are not amongst the favored design patterns and are somewhat regarded as anti-patterns.

check
mocking a singleton class

Related

In Java unit testing, how to mock the variables that are not injected but created inside the to-be-tested class?

For example, the class to be tested is
public class toBeTested {
private Object variable;
public toBeTested(){
variable = someFactory(); // What if this someFactory() sends internet request?
// Can I mock "variable" without calling
// someFactory() in testing?
}
public void doSomething(){
...
Object returnedValue = variable.someMethod(); // In testing, can I mock the behavior of
// this someMethod() method when
// "variable" is a private instance
// variable that is not injected?
Object localVariable = new SomeClass(); // Can I mock this "localVariable" in
// testing?
...
}
}
My questions are as stated in the comments above.
In short, how to mock the variables that are not injected but created inside the to-be-tested class?
Thanks in advance!
Your question is more about the design, the design of your class is wrong and it is not testable, It is not easy (and sometimes it is not possible at all) to write a unit test for a method and class that have been developed before. Actually one of the great benefit of TDD(Test Driven Development) is that it helps the developer to develop their component in a testable way.
Your class would have not been developed this way if its test had been written first. In fact one of the inevitable thing that you should do when you are writing test for your component is refactoring. So here to refactor your component to a testable component you should pass factory to your class's constructor as a parameter.
And what about localVariable:
It really depends on your situation and what you expect from your unit to do (here your unit is doSomething method). If it is a variable that you expext from your method to create as part of its task and it should be created based on some logic in method in each call, there is no problem let it be there, but if it provides some other logic to your method and can be passed as parameter to your class you can pass it as parameter to your class's cunstructor.
One more thing, be carefull when you are doing refactoring there will be many other components that use your component, you should do your refactoring step by step and you should not change the logic of your method.
To add another perspective: If faced with situations in which you have to test a given class and aren't permitted to change the class you need to test, you have the option to use a framework like PowerMock (https://github.com/powermock/powermock) that offers enhanced mocking capabilities.
But be aware that using PowerMock for the sole purpose of justifying hard to test code is not advisable. Tashkhisi's answer is by far the better general purpose approach.

java - testing - lambda with inner private method?

I have some problems with unit testing the following method.
public List<GetSupplyChainResponse> getSupplyChains(){
List<GetSupplyChainsResponse> response = new ArrayList<>();
supplyChainRepository.findSupplyChainsWithCompound().forEach(result
-> response.add(getGetSupplyChainSimpleResponse(result)));
return response;
}
getGetSupplyChainSimpleResponse() is a private method of the same class as getSupplyChains()
Is there any possibility to define return values therefore or do you have any other ideas how I could test the method getSupplyChains()?
You might be overthinking this. The fact that the method that you want to test (getSupplyChains) uses a lambda that calls a private method is irrelevant: they are just implementation details.
What you unit test is the part of your class that you as a client interact with, i.e. its interface. You typically call a public method with some arguments (in this case there are none), you get some return value and that is what you verify in your unit test. If your public method makes use of some private method, it will be tested also.
The problem here is that the response that you get from getSupplyChains obviously depends on what supplyChainRepository.findSupplyChainsWithCompound() returns. What you do in this case is mock that dependency (supplyChainRepository) out: you create a mock instance of SupplyChainRepository, you tell it how to behave, and you pass it to this class, for example via the constructor.
You can either write the mock yourself, or you can rely on a mocking framework to do the heavy lifting like Mockito.
I definitely recommend against unit testing private methods (it leads to brittle tests), or increasing the visibility of those methods (a.k.a. sacrificing your design for the sake of testing).
It is a commonly discussed problem, some prefer using reflection as Janos Binder recommended (How to call a private method from outside a java class), some can live with the fact the the visibility of the methods which we need to mock is increased for the sake of testability.
The problem is quite well discussed here: How do I test a class that has private methods, fields or inner classes?. You can see from the answers and wide discussions that the topic is quite complicated and developers split into factions and use different solutions.
I'd recommend you to remove the private access modifier and to make the method package private (use the default visibility). The common custom is to have the test classes in the same package (but not in the same folder!) as the tested classes.
This will allow you to:
Test the getGetSupplyChainSimpleResponse() method itself, which you should do in any case somehow.
Mock its behaviour for the purpose of testing getSupplyChains(). This you will achieve e.g. by using Mockito framework and its #Spy functionality.
For those who argue that this is "sacrificing your design for the sake of testing", I would answer that if you have private methods which need to be mocked and/or tested, then the design is not ideal anyway so changing the visibility to package private does not mean too big deterioration. The clear solution (from the object oriented design's point of view) is to delegate the behavior of such private methods to separate classes. However, sometimes in the real life it is just overkill.

java - Allow extending static method in sub classes

Using JUnit all my runner classes implement a method that is annotated with
#BeforeClass
public static void setUp() throws Exception {}
There is a lot of mutual code.
I want to create a base runner that will hold all the base code and will allow sub classes to add more features.
This is all static. What is the best practice?
You should reconsider your design. The #BeforeClass annotation is intended to specify code that has to run exactly once for all tests. If you repeat the same code in multiple static methods annotated with #BeforeClass, in other words, execute the same action multiple times, it suggests that it is not the #BeforeClass semantic that you want.
Maybe you just want instance methods annotated with #Before
Otherwise, if it’s really about single time actions, just put a static method with the #BeforeClass annotation into the base class, and you’re done. The initialization of the subclass implies the initialization of the base class. The initialization of the base class will happen exactly once for all subclasses but that is what #BeforeClass is all about. As said, if you want an initialization once per subclass or once per test, it’s more likely that #Before is the feature you want.
Note further, that you can have code in static methods in a base class which is only executed when subclasses invoke it. Just place the code into a method without the #BeforeClass annotation. Then, methods in subclasses, having the annotation or not, may invoke the method of the base class. There is no need for an override relationship here.
As said; there is no "overriding" for static; and of course: static is by itself ... very often an indication for "design improvement required". Everybody who is writing serious unit tests knows that static things can make unit testing a night-mare. So we avoid static in our production code. But then, in our testing code, we just use it?!
And going one step further: some people claim that inheritance is not a good answer to "i have a lot of common code within my unit tests".
See here for example.
You could move the common code to a rule and reuse that rule in every test: https://github.com/junit-team/junit/wiki/Rules

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 to mock object construction?

Is there a way to mock object construction using JMock in Java?
For example, if I have a method as such:
public Object createObject(String objectType) {
if(objectType.equals("Integer") {
return new Integer();
} else if (objectType.equals("String") {
return new String();
}
}
...is there a way to mock out the expectation of the object construction in a test method?
I'd like to be able to place expectations that certain constructors are being called, rather than having an extra bit of code to check the type (as it won't always be as convoluted and simple as my example).
So instead of:
assertTrue(a.createObject() instanceof Integer);
I could have an expectation of the certain constructor being called. Just to make it a bit cleaner, and express what is actually being tested in a more readable way.
Please excuse the simple example, the actual problem I'm working on is a bit more complicated, but having the expectation would simplify it.
For a bit more background:
I have a simple factory method, which creates wrapper objects. The objects being wrapped can require parameters which are difficult to obtain in a test class (it's pre-existing code), so it is difficult to construct them.
Perhaps closer to what I'm actually looking for is: is there a way to mock an entire class (using CGLib) in one fell swoop, without specifying every method to stub out?
So the mock is being wrapped in a constructor, so obviously methods can be called on it, is JMock capable of dynamically mocking out each method?
My guess is no, as that would be pretty complicated. But knowing I'm barking up the wrong tree is valuable too :-)
The only thing I can think of is to have the create method on at factory object, which you would than mock.
But in terms of mocking a constructor call, no. Mock objects presuppose the existence of the object, whereas a constructor presuppose that the object doesn't exist. At least in java where allocation and initialization happen together.
jmockit can do this.
See my answer in https://stackoverflow.com/questions/22697#93675
Alas, I think I'm guilty of asking the wrong question.
The simple factory I was trying to test looked something like:
public Wrapper wrapObject(Object toWrap) {
if(toWrap instanceof ClassA) {
return new Wrapper((ClassA) toWrap);
} else if (toWrap instanceof ClassB) {
return new Wrapper((ClassB) toWrap);
} // etc
else {
return null;
}
}
I was asking the question how to find if "new ClassAWrapper( )" was called because the object toWrap was hard to obtain in an isolated test. And the wrapper (if it can even be called that) is kind of weird as it uses the same class to wrap different objects, just uses different constructors[1]. I suspect that if I had asked the question a bit better, I would have quickly received the answer:
"You should mock Object toWrap to match the instances you're testing for in different test methods, and inspect the resulting Wrapper object to find the correct type is returned... and hope you're lucky enough that you don't have to mock out the world to create the different instances ;-)"
I now have an okay solution to the immediate problem, thanks!
[1] opening up the question of whether this should be refactored is well out of the scope of my current problem :-)
Are you familiar with Dependency Injection?
If no, then you ceartanly would benefit from learning about that concept. I guess the good-old Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler will serve as a good introduction.
With Dependency Injection (DI), you would have a DI container object, that is able to create all kinds of classes for you. Then your object would make use of the DI container to instanciate classes and you would mock the DI container to test that the class creates instances of expected classes.
Dependency Injection or Inversion of Control.
Alternatively, use the Abstract Factory design pattern for all the objects that you create. When you are in Unit Test mode, inject an Testing Factory which will tell you what are you creating, then include the assertion code in the Testing Factory to check the results (inversion of control).
To leave your code as clean as possible create an internal protected interface, implement the interface (your factory) with the production code as an internal class. Add a static variable type of your interface initialized to your default factory. Add static setter for the factory and you are done.
In your test code (must be in the same package, otherwise the internal interface must be public), create an anonymous or internal class with the assertion code and the test code. Then in your test, initialize the target class, assign (inject) the test factory, and run the methods of your target class.
I hope there is none.
Mocks are supposed to mock interfaces, which have no constructors... just methods.
Something seems to be amiss in your approach to testing here. Any reason why you need to test that explicit constructors are being called ?
Asserting the type of returned object seems okay for testing factory implementations. Treat createObject as a blackbox.. examine what it returns but dont micromanage how it does it. No one likes that :)
Update on the Update: Ouch! Desperate measures for desperate times eh? I'd be surprised if JMock allows that... as I said it works on interfaces.. not concrete types.
So
Either try and expend some effort on getting those pesky input objects 'instantiable' under the test harness. Go Bottom up in your approach.
If that is infeasible, manually test it out with breakpoints (I know it sucks). Then stick a "Touch it at your own risk" comment in a visible zone in the source file and move ahead. Fight another day.

Categories