Not able to mock static methods using Powermock (with EasyMock) - unit-testing

I want to mock a static method and also non-static methods of a class.
My source looks like:
public class XDSUtilityManager
{
private static XDSUtilityManager xdsUtilMgr = new XDSUtilityManager();
private XDSUtilityManager()
{
xdsUtilMgrImpl = new XDSUtilityManagerImpl();
}
public static XDSUtilityManager getInstance()
{
return (xdsUtilMgr == null ) ? new XDSUtilityManager() : xdsUtilMgr;
}
public XMLDocument getXMLDocument(final String absoluteKey, final XDSClient xdsClient)
{
return getXMLDocument(absoluteKey, xdsClient, false);
}
}
I want to mock static method getInstance(). I want getInstance() to return mock object of XDSUtilityManager class. Also I want to mock getXMLDocument() which is not static.
And in my testCase I tried following:
XMLDocument xmlDocument = PowerMock.createMock(XMLDocument.class);
XDSUtilityManager xdsUtilityManager = PowerMock.createPartialMock(XDSUtilityManager.class,"getXMLDocument");
PowerMock.mockStaticPartial(XDSUtilityManager.class, "getInstance");
expect(XDSUtilityManager.getInstance()).andReturn(xdsUtilityManager).anyTimes();
expect(xdsUtilityManager.getXMLDocument((String)anyObject(), anyObject(XDSClient.class))).andReturn(xmlDocument).anyTimes();
PowerMock.replay(xdsUtilityManager);
PowerMock.replay(xmlDocument);
But things are not working as expected. Please help

The easiest way I have found to do this is by using PowerMockito. PowerMockito is a combination of Mockito and PowerMock, which allows the mocking of static objects.
The pattern I have used is to use the mock your static getInstance() to return a copy of your non static mock, which you then extend as normal. An example using PowerMockito would be:
#RunWith(PowerMockRunner.class)
#PrepareForTest({SingletonObject.class})
public class SingletonTester {
#Mock
private SingletonObject singleMock;
#Before
public void setup(){
// initialize all the #Mock objects
MockitoAnnotations.initMocks(this);
// mock all the statics
PowerMockito.mockStatic(SingletonObject.class);
}
#Test
public void mockTester(){
// Mock the static getInstance call to return the non-Static Mock
Mockito.when(SingletonObject.getInstance()).thenReturn(singleMock);
// Mock the non static version as normal
PowerMockito.when(singleMock.nonStaticMethodCall()).thenReturn("Whatever you need.");
//..........
}
}
Your static call to getInstance() to get the singleton object returns the instantiated mock object you ALSO define. Once you tell the static what to return, you can continue to mock the non-static calls as normal.

Its not required to call getInstance() method to create the instance of XDSUtilityManager.
Using PowerMockito, as your constructor is private you need to suppress the constructor before you call create mock as below..
PowerMockito.suppress(PowerMockito.constructor(XDSUtilityManager.class));
// enable static mocking for all the methods in the class
PowerMockito.mockStatic(XDSUtilityManager.class);
XDSUtilityManager xDSUtilityManager = PowerMockito.mock(XDSUtilityManager.class);
XMLDocument xmlDocument = PowerMock.createMock(XMLDocument.class);
PowerMockito.when(xDSUtilityManager.getXMLDocument(
Mockito.anyString(),Mockito.anyObject())).thenReturn(xmlDocument);

Related

Mockito Inline Mock Maker - throws Exception - Argument passed to when() is not a mock

I wanted to mock static methods, hence used dependency "mockito-inline" 3.8 version instead of "mockito-core"
The static method mocks work fine but my old tests that mock interfaces fail with the below error
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();
Reverting to using mockito-core solves the issue but then I would not be able to mock static methods
Is there any way we can choose different mockito engines (Subclass/Inline) for each class?
MockResolver fixed the issue as described in https://github.com/mockito/mockito/issues/1980
If you need to mock static methods and you cannot use mockito-inline you could do something like this with mockito-core:
public class MockitoUtil {
public static <T, S> void mockStaticMethod(Class<T> classToMock, String nameOfMethodToMock, S result) {
MockCreationSettings<T> settings = mock(MockCreationSettings.class);
when(settings.isSerializable()).thenReturn(true);
MockHandler<T> handler = new MockHandler<>() {
private static final long serialVersionUID = 1L;
#Override
public Object handle(Invocation invocation) throws Throwable {
String invokedMethodName = invocation.getMethod().getName();
if(!invokedMethodName.equals(nameOfMethodToMock)){
String message = "called %s on class %s, but only %s was implemented";
throw new Exception(String.format(message, invokedMethodName, classToMock.getName(), nameOfMethodToMock));
}
return result;
}
#Override
public MockCreationSettings<T> getMockSettings() { return null; }
#Override
public InvocationContainer getInvocationContainer() { return null; }
};
MockMaker.StaticMockControl<T> classToMockControl = Mockito
.framework()
.getPlugins()
.getInlineMockMaker()
.createStaticMock(classToMock, settings, handler);
classToMockControl.enable();
}
}
N.B. you should call classToMockControl.disable() after the static method invocation if you'd like to mock static methods of other classes in the same test

How to write unit tests for classes with CheckedProviders in their constructors

I have a class under test whose constructer looks like this :
public class ClassUnderTest {
ClientOne clientOne;
ClientTwo clientTwo;
OtherDependency otherDependency;
#Inject
public ClassUnderTest(MyCheckedProvider<ClientOne> myCheckedProviderOne,
MyCheckedProvider<ClientTwo> myCheckedProviderTwo,
OtherDependency otherDependency) throws Exception {
this.clientOne = myCheckedProviderOne.get();
this.clientTwo = myCheckedProviderTwo.get();
this.otherDependency = otherDependency;
}
.
.
.
}
And the CheckedProvider looks thus :
public interface MyCheckedProvider<T> extends CheckedProvider<T> {
#Override
T get() throws Exception;
}
I could mock the clients, but how do I initialise the providers with my mocked clients.I use a combination of junit and mockito for writing tests.Any inputs would be appreciated.
What you could do is to mock providers rather than clients. ClientOne and ClientTwo are the types you are passing into your generic class, they are not variables and hence not something you want to mock. In contrast, the providers you are passing to the constructor are really variables, and what you need to control (simulate) are the behaviors of these variables.
public class ClassTest {
private static final CientOne CLIENT_ONE = new ClientOne();
private static final ClientTwo CLIENT_TWO = new ClientTwo();
#Mock
private MyCheckedProvider<ClientOne> providerOne;
#Mock
private MycheckedProvider<ClientTwo> providerTwo;
private ClassUnderTest classUnderTest;
#Before
public void setUp() {
when(providerOne.get()).thenReturn(CLIENT_ONE);
when(providerTwo.get()).thenReturn(CLIENT_TWO);
classUnderTest = new ClassUnderTest(providerOne, providerTwo, otherDependency);
}
}
As the other answer suggests, you could easily mock the providers, too.
But youMyCheckedProvider don't have to.
You already have an interface sitting there, so what would prevent you from creating something like
class MyCheckedProviderImpl<T> implements MyCheckedProvider<T> {
and that think takes a T object in its constructor and returns exactly that?
That is more or less the same what the mocking framework would be doing.

How do I mock a static method in final class

I have some code that has a static method inside a final class. I was trying to mock that method. I have tried doing a few things..
public final Class Class1{
public static void doSomething(){
}
}
How can I mock doSomething()? I have tried..
Class1 c1=PowerMockito.mock(Class1.class)
PowerMockito.mockSatic(Class1.class);
Mockito.doNothing().when(c1).doSomething();
This gives me an error:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.cerner.devcenter.wag.textHandler.AssessmentFactory_Test.testGetGradeReport_HTMLAssessment(AssessmentFactory_Test.java:63)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:260)
Most used testing framework is JUnit 4. So if you are using it you need to annotate test class with:
#RunWith( PowerMockRunner.class )
#PrepareForTest( Class1.class )
Than
PowerMockito.mockSatic(Class1.class);
Mockito.doNothing().when(c1).doSomething();
Mockito.when(Class1.doSomething()).thenReturn(fakedValue);
// call of static method is required to mock it
PowerMockito.doNothing().when(Class1.class);
Class1.doSomething();
I use PowerMock. It let's you do things Mockito can't do.
https://github.com/powermock/powermock/wiki
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticClass.class)
public class StaticTest {
#Before
public void setUp() {
PowerMockito.mockStatic(Bukkit.class);
//When a static method with no arguments is called.
when(StaticClass.callMethod1()).thenReturn(value);
//When a static method with an argument is called.
when(StaticClass.callMethod2(argument)).thenReturn(value2);
//Use when you don't care what the argument is..
//use Mockito.anyInt(), Mockito.anyDouble(), etc.
when(StaticClass.callMethod3(Mockito.anyString())).thenReturn(value3);
}
#Test
public void VerifyStaticMethodsWork() {
assertEquals(value, StaticClass.callMethod1());
assertEquals(value2, StaticClass.callMethod2(argument));
assertEquals(value3, StaticClass.callMethod3("Hello"));
}
}

Unit test for EJB with #PostConstruct method

Consider the following sample code:
#Stateless
public class MyBean {
private SomeHelper helper;
private long someField;
#PostConstruct
void init() {
helper = new SomeHelper();
someField = initSomeField();
}
long initSomeField() {
// perform initialization
}
public void methodToTest() {
helper.someMethod();
long tmp = 3 + someField;
}
}
And here is the test template, that I always use
public class MyBeanTest {
#Spy
#InjectMocks
private MyBean testSubject;
#Mock
private SomeHelper mockedHelper;
#Before
public void before() {
MockitoAnnotations.initMocks(this);
doReturn(1L).when(testSubject).initSomeField();
}
#Test
public void test() {
testSubject.methodToTest();
// assertions
}
}
The problem with testing methodToTest is that it needs field someField to be initialized. But the initialization is done in #PostConstruct method. And I can't run this method before call to testSubject.methodToTest(), because it will re-initialize helper. Also, I don't want to manually set up all the mocks. And I don't want to use reflection to set the someField, because that would make MyBeanTest vulnerable to MyBean refactoring. Can anybody propose, maybe better design to avoid situations like this?
A few notes:
Logic in initSomeField could be quite heavy (including calls to database), so I want to initialize it only once in a #PostConstruct method.
I don't want to create a setter for this field or widen its access modifier, because that would allow unwanted changes to my field.
If your test is in the same package as your class, then you can just call initSomeField directly, since it's package private. You can either do this in each individual test method, or in your #Before method, provided it runs after initMocks.

Unable to get mocked instance of Executor in separate class

I am trying to mock ExecutorService and Executors from java.util.concurrent package.
I am able to get the mocked object if I try to get the object within the same class (test class) where I am mocking the object. However if I try to get the mocked object in a different class (the class I want to test) then it returns actual object from java.util.concurrent. Following is the code snippet.
The class I want to test:
public class MyClass
{
public void myMethod()
{
ExecutorService executorService = Executors.newFixedThreadPool(2, new MyThreadFactory());
for (int count = 0; count < 2; count++)
{
executorService.submit(new Thread());
}
}
}
class MyThreadFactory implements ThreadFactory
{
#Override
public Thread newThread(Runnable r)
{
return null;
}
}
My Test class looks like:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Executors.class)
public class MyClassTest
{
#Test
public void testMyMethod()
{
prepareMocks();
//Code to get mocked object (See testMethod below)
}
private void prepareMocks()
{
ExecutorService executorService = PowerMock.createMock(ExecutorService.class);
EasyMock.expect(executorService.submit(EasyMock.anyObject(Runnable.class))).andReturn(null).anyTimes();
PowerMock.mockStatic(Executors.class);
EasyMock.expect(Executors.newFixedThreadPool(EasyMock.anyInt(), EasyMock.anyObject(ThreadFactory.class))).andReturn(executorService).anyTimes();
PowerMock.replay(executorService, Executors.class);
}
}
If MyClassTest.testMyMethod() is as below, it returns mocked oject.
#Test
public void testMyMethod()
{
prepareMocks();
//Following code reurned mocked instance of ExecutorService
ExecutorService executorService = Executors.newFixedThreadPool(2, new MyThreadFactory());
for (int count = 0; count < 2; count++)
{
executorService.submit(new Thread());
}
}
However if I change the test method to call myClass.myMethod() it returns actual instance instead of mocked instance in myMethod().
#Test
public void testMyMethod()
{
prepareMocks();
/*
* Within myClass.myMethod(), Executors.newFixedThreadPool() returns actual instance of ThreadPoolExecutor
* instead of mocked object
*/
MyClass myClass = new MyClass();
myClass.myMethod();
}
I am expecting to get a mocked instance of Executors/ExecutorService in myClass.myMethod.
Is this the expected behavior? Could anyone explain the behavior? Am I missing anything?
You need to let the class know that there is going to be a Mock incoming. In your #PrepareForTest(), try also including the class that is calling the static. This way you are telling it to mock the execution of the static, as well as telling it where this mock is going to be taking place. Try updating the #PrepareForTest({Executors.class, MyClass.class}).
When you have it so your test class is calling the static directly, you have the Executors.class in the #PrepareForTest() so it will know to "inject" that mock into the execution. When you call your other class, at runtime the class you are calling it doesn't know to use the mock version of your static class, which is why it is resorting to the original code that it knows about, not the mock outside its scope. Adding the class that CALLS the static object (the one you test), will allow the static mock you have to be hooked in when it is ran.