Powermock createPartialMockForAllMethodsExcept throwing null pointer because field is null? - java

I'm using powermock like so:
DetailServiceImpl impl=PowerMock.createPartialMockForAllMethodsExcept(
DetailServiceImpl.class, "getServiceDetail", JSONObject.class,String.class);
Whitebox.invokeMethod(impl,"getServiceDetail",response,dateFormat.format(date).toString());
However, when this line is run, "getServiceDetail" is executed and a null pointer exception is thrown because the method being mocked on the class DetailServiceImpl uses a class field that is autowired by spring, but on this mock it is null.
By the time I've made this assignment to the variable impl, the method is already run so I can't just do:
impl.setField(myFieldObjMock);
because it's already too late.
How can I fix this issue so that I can either set this field before the method is ran, or have powermock not leave this field null?
____Edit: added WhiteBox call in test in code example_____

Related

Unable to mock enum static method with null parameter

I am trying to mock a static method of enum which has null value like below
try (MockedStatic<SomEnum> e = Mockito.mockStatic(SomEnum.class)) {
e.when(() -> SomEnum.methodWhichAcceptingNullParam(any())).thenReturn(somValue);
}
here any() is not working... i am not sure I am passing null parameter inside method
methodWhichAcceptingNullParam
I have tried both any and isNull.The fact is SomEnum.methodWhichAcceptingNullParam is always get called however it should not because I provided a mocked value already
any help?
Is your code called with a null or not-null object? This information is missing (at least for me).
Assuming you are calling SomeEnum.methodWhichAcceptingNullParam(null), then you need to use
ArgumentMatchers.isNull()
instead of any().

NullPointerException when using Mockito thenCallRealMethod

I have a question regarding using Mockito thenCallRealMethod. I've read the warnings about using this function; basically I want to write this into my test to futureproof my application logic, because it's being used as a library and I want to make sure users of my library have futureproof protection.
My test case looks like this:
#Test
public void Test() {
when(restTemplate.postForEntity(...)).thenReturn(new ResponseEntity<>(realObjectMapper.writeValueAsString(data), HttpStatus.OK));
when(objectMapper.readValue(realObjectMapper.writeValueAsString(data), TestData.class)).thenCallRealMethod();
TestData result = tested.callMethod(...);
....
}
TestData is a simple POJO which contains a bunch of fields but nothing particularly interesting, and data is an instance of TestData. objectMapper is a mocked instance of FasterXML Jackson ObjectMapper, and realObjectMapper is a real (unmocked) instance of the same class.
The problem I'm having is a NullPointerException when my application attempts to execute objectMapper.readValue (on the mocked instance) as per the thenCallRealMethod on the second line of the test. I've verified that when I pass the same inputs to realObjectMapper.readValue then it executes fine, so there is nothing wrong with the input. What am I missing?
Stack trace:
java.lang.NullPointerException
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)
.... (my code here)
When you use a mocked object then the real object is not initialized. That means any property even with a default value will be null.
In my case I had a property injected with #Value from a properties file, but if I define a default value it happens the same, it is null when it is going to be used.
Solution: Yo have to check which is the property causing the null pointer exception on the method and then either mock a getter that returns the expected value of that property and call the getter from your real method or set its value with a setter from the test, after the mock object is created

Unable to mock a class with a method that chains an interface in Java

I am trying to mock a class with Mockito that has a method which chains an interface. The class is mocked successfully but when it calls the interface a null pointer is thrown. The code looks as below:
mock = Mockito.mock(MyProcess.class);
process = mock.getProcess()
.getService() //Interface throwing null exception
.startProcessInstanceByKey("String argument");
I got this solution and tried to follow the example on the page below but its not working: https://static.javadoc.io/org.mockito/mockito-core/2.13.0/org/mockito/Mockito.html#RETURNS_DEEP_STUBS
Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS);
// note that we're stubbing a chain of methods here: getBar().getName()
when(mock.getBar().getName()).thenReturn("deep");
// note that we're chaining method calls: getBar().getName()
assertEquals("deep", mock.getBar().getName());
The example above is not working
You need to mock the retuning Service, too. All external dependencies of you classes need to be mocked and if you doesn´t do this you get null.
processMock = Mockito.mock(MyProcess.class);
serviceMock= Mockito.mock(Service.class);
Mockito.doReturn(serviceMock).when(processMock).getService();
Mockito.doReturn(<VALUE>).when(serviceMock).startProcessInstanceByKey("String argument");
You need to mock every step with external values - this is how it works.

any(object.class) throwing null in mockito

I have the following class:
mockStatic(Exception.class);
PowerMockito.doNothing().when(Exception.class);
Exception.throwErrorIfExists(any(Object.class)); // line3
In exception class,method is defined as follows:
static void throwErrorIfExists(def model){
if(model.hasErrors())
throwError(model)
}
The following exception is thrown at line 3: Cannot invoke method hasErrors() on null object
java.lang.NullPointerException: Cannot invoke method hasErrors() on null object
How can any(object.class) be NULL in any circumstances because any simply means return any anything?
I think you are misusing the any() method. This method exists so that you can verify interactions with mocks, e.g. you can say:
// checks yourMethod() was invoked with any argument
verify(mockedObject).yourMethod(any(SomeClass.class));
If you want to call your method with some arbitrary object, you should create the object in your test and pass it in. any() is not a method that just makes objects for you.
You can't invoke ThrowErrorIfExists with a null parameter, as you invoke a method (hasErrors() on it. This has nothing to do with any mocking, but it is just an error in your method.
You use a matcher to call the method
Exception.throwErrorIfExists(any(Object.class));
which is quite strange; matchers are used to configure the behaviour of a mock like
PowerMockito.doNothing().when(Exception.throwErrorIfExists(any(Object.class)));
Then you can call throwErrorIfExists with any object to trigger the "do nothing".

Mock Documentum IDfSession using Mockito

I have the following (simplified) function which I wish to check using JUnit:
protected IDfCollection getCollection(IDfSession session) throws DfException{
IDfQuery dfcQuery = new DfQuery();
dfcQuery.setDQL(MY_DQL);
return dfcQuery.execute(session, IDfQuery.READ_QUERY);
}
I have successfully tested it using real IDfSession, but I would like do it without connecting to the repository. So I tried to mock empty IDfSession using:
IDfSession mockedSession = Mockito.mock(IDfSession.class);
But I was given NullPointerException:
Caused by: java.lang.NullPointerException
at java.util.StringTokenizer.<init>(StringTokenizer.java:182)
at java.util.StringTokenizer.<init>(StringTokenizer.java:204)
at com.documentum.fc.internal.util.SoftwareVersion.<init>(SoftwareVersion.java:53)
at com.documentum.fc.client.DfQuery.runQuery(DfQuery.java:136)
at com.documentum.fc.client.DfQuery.execute(DfQuery.java:208)
Not knowing what actually went wrong (which function of the mocked object returned null which was not expected) I created a simple class implementing IDfSession interface and used code coverage tool to check which function was called. I hoped to mock behavior of the function later using mockito. I seemed to be getServerVersion so I changed returned null to real value "6.5.0.355 SP3P0600 Linux.Oracle". Next called function was getBatchManager so I mocked returned object here as well. But now I get:
Caused by: java.lang.ClassCastException: com.example.model.mock.IDfSessionMocked cannot be cast to com.documentum.fc.client.impl.session.ISession
I tried to implement ISession interface in the IDfSessionMocked class, but it does not compile, for instance because one of the used types (namely com.documentum.fc.client.impl.session.ISessionListener) is not visible.
Here: http://www.informedconsulting.nl/blog/?p=187 I found information how to do it using powerMock. Another difference is that object is taken directly from session not using IDfQuery.
What should I do?
Update after comment
getBatchManager function was mocked and now it returns anonymous inner class object, with all the returned values set to false or 0 depending on the expected returned type. Function isFlushBatchOnQuery has been called according to coverage tool.
I am not an expert of Documentum but I think you need a more complex object, you could have a look at this repo https://github.com/ValentinBragaru/dfc-mock
IDfSessionMock is what you need I think.
I hope it helps.

Categories