I am trying to verify a static method was never called while testing a service method with powerMockito 1.6.4
I followed This answer to do the same.
following is my code.
#RunWith ( PowerMockRunner.class)
#PrepareForTest ( MyClass.class)
#PowerMockIgnore ( "javax.net.ssl.*")
public class SomeTests
{
#Test
public void testMyMethodIsNotCalled() throws Exception
{
PowerMockito.mockStatic(MyClass.class);
underTest.testMethod();
PowerMockito.verifyStatic(Mockito.never());
MyClass.myMethod(Mockito.any());
}
}
The problem I am facing now is that, MyClass.myMethod(Mockito.any()); calls the real myMethod and gives a nullPointerException.
My assumption is that MyClass.myMethod(Mockito.any()); works with PowerMockito.verifyStatic(Mockito.never()); in order to specify the static method to be verified.
Am I missing something?
you have to mock the static method behaviour also
i.e. something like this
PowerMockito.mockStatic(NameOfClass.class);
expect( NameOfClass.nameOfMethod((URL)Mockito.any(),Mockito.anyString())).andReturn(actualOutput);
refer Mock method with parameters
Related
Can I pass mocked object as an argument to thenThrow() method? I have something like this:
public class MyException extends Exception {
public MyException(MockedClass mockedClass) {
super("My message:" + mockedClass.doSth("foo"));
}
}
public class TestedServiceTest {
#Mock
MockedClass mockedClass;
#Mock
AnotherClass anotherClass;
#Before
public void init() {
when(mockedClass.doSth(anyString())).thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocation) throws Throwable {
return invocation.getArgument(0);
}
});
}
#Test
public void notWorkingTestMethod() {
when(anotherClass.doSomething()).thenThrow(new MyException(mockedClass));
}
notWorkingTestMethod() throws org.mockito.exceptions.misusing.UnfinishedStubbingException
However if I use the same technique on void method it doesn't complain anymore:
#Test
public void workingTestMethod() {
doThrow(new MyException(mockedClass)).when(anotherClass).doSomethingVoid();
}
}
Is there any other possible reason it doesn't work?
To understand why this is happening you need to understand a bit about how Mockito works.
Mockito uses internal static state to keep track of what setup is being done to which mocks. This does allow for clear and expressive mocking, but sometimes it does cause a violation of the Principle of Least Astonishment, as it seems you've encountered here.
Let's consider the line in your not-working test method:
when(anotherClass.doSomething()).thenThrow(new MyException(mockedClass));
Mockito sees these interactions, in the following order:
a call to anotherClass.doSomething(), which Mockito will record internally as the last invocation on a mock, because this mock method might be about to be set up to do something.
a call to the static when method, so Mockito knows that the behaviour of anotherClass.doSomething() is being set up.
a call to mockedClass.doSth() in the MyException constructor. This is another invocation on a mock, which Mockito wasn't expecting.
At this point, the doThrow() method hasn't been called, so Mockito can't know that you will later call it to set up the exception to throw. Instead, it looks to Mockito as if you are writing:
when(anotherClass.doSomething());
when(mockedClass.doSth()).then....
Hence the exception about unfinished stubbing.
The fix, as suggested by #marcellorvalle in the comment, is to move the exception out into a local variable:
MyException myException = new MyException(mockedClass);
when(anotherClass.doSomething()).thenThrow(myException);
In most cases, extracting a local variable like this won't change the behaviour of the code. But it does change the order of the three interactions with Mockito I listed above. It is now:
a call to mockedClass.doSth() in the constructor of your exception, which Mockito will record internally as the last invocation on a mock.
a call to anotherClass.doSomething(), which Mockito will record internally as the last invocation on a mock, replacing the previous one.
a call to the static when method, so Mockito knows that the behaviour of anotherClass.doSomething() is being set up.
The next interaction with Mockito is then the call to thenThrow(), which Mockito can then link to the call to anotherClass.doSomething().
As for your workingTestMethod() method, it has the line
doThrow(new MyException(mockedClass)).when(anotherClass).doSomethingVoid();
This mock setup works, because this time, the order of interactions with Mockito is:
a call to mockedClass.doSth() in the constructor of your exception, which Mockito will record internally as the last invocation on a mock. (It happens that in this case, this last-invocation isn't used.)
a call to the static doThrow() method. At this point, Mockito doesn't know what mock or what method to throw the exception for, so it can only make a note of the exception.
a call to the when method on the Stubber instance that doThrow() returns. This tells Mockito which mock is being set up, and also to watch out for whatever the next invocation of a mock method is, as that is what is being set up. It looks like this when method returns the mock that it is given.
a call to the doSomethingVoid() method of your mock. Mockito can then link the exception that was to be thrown to this method.
I've been trying to figure out what's the deal with PowerMockito's constructor mocking. My code is similar to the following:
public void testConstruction() {
whenNew(Account.class).withAnyArguments().thenReturn(mock(Account.class));
assertNotNull(new Account("name")); //fails
}
I'm not really sure where else to look for to find what's causing this issue. With the above stubbing code, PowerMockito will only return the object created by mock(Account.class) when I call the constructor with no arguments; it's acting as if I stubbed it using withNoArguments(). I'm sure that my test class is set up correctly because the following code passes:
public void testConstruction() {
whenNew(Account.class).withArguments("name").thenReturn(mock(Account.class));
assertNotNull(new Account("name")); //passes
}
I ran into similar issue. withAnyArguments doesn't behave as expected if the class being mocked has more than one constructor. In my case the class mocked with whenNew had 2 constructors and I would always get null when new instance of this class was created. https://github.com/powermock/powermock/issues/891 gave some hint and I switched to using withArguments.
I am having some trouble trying to unit test java code that at some point calls native methods. Basically, I am trying to use PowerMockito to mock the class that will eventually call native. I was able to mock non-void methods just fine, but I keep getting compilation errors when I try to mock a method of void return type. Here is an example of the code I'm trying to test:
public class ClassThatCallsNative {
void initObject(ByteBuffer param1, int param2) {
//calls native
}
int getId(int param1) {
//calls native
}
}
I have this code in my test class:
PowerMockito.when(mClassThatCallsNative.getId(Mockit.anyInt())).thenReturn(0);
This line of code compiles just fine, however the following line is where I get compilation error:
PowerMockito.when(mClassThatCallsNative.initObject(Mockit.any(ByteBuffer.class), anyInt())).doNothing();
The error message just says invalid void parameter and points to .initObject.
Any idea what I am doing wrong?
Since you are trying to mock method which returns void, you simply can't call it inside when() method. This is because PowerMockito.when() methods expects T methodCall but got void, this is the reason for compilation failure.
Instead you should use this syntax:
PowerMockito.doNothing().when(mClassThatCallsNative).initObject(any(ByteBuffer.class), anyInt())
any() and anyInt() methods are part of Mockito class.
For void methods, you need to use below one
PowerMockito.doNothing().when(mClassThatCallsNative.initObject(Mockit.any(ByteBuffer.class), anyInt()))
Figured out what the problem was, at last. Turns out I needed the instance of ClassThatCallsNative in order to mock it's methods. What was happening before is that the object was being initialized inside a constructor call, but when I created another constructor that takes ClassThatCallsNative as a parameter, and set my instance to that instead, everything worked fine.
Thank you anyways!
I've developed an application in Java and I'm trying to create unit tests using Powermockito (I should add that I'm new to unit testing).
I have a class called Resource which has a static method called readResources:
public static void readResources(ResourcesElement resourcesElement);
ResourcesElement is also coded by me.
In testing, I want to create my own Resource, so I want the above method to do nothing.
I tried using this code:
PowerMockito.spy(Resource.class);
PowerMockito.doNothing().when(Resource.class, "readResources", Matchers.any(ResourcesElement.class));
The unit test throws an exception:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:36)
Powermockito also suggest that I should use thenReturn or thenThrow after when, but it seems that the method 'when' returns void when it is called after doNothing (which is logical).
If I try:
PowerMockito.when(Resource.class, "readResources", Matchers.any(ResourcesElement.class)).....
doNothing is not an option after when.
I managed to make methods without arguments to do nothing, using the 2 arguments version of the method. For example:
PowerMockito.doNothing().when(Moduler.class, "startProcessing");
This works (startProcessing doesn't take any arguments).
But how can I make methods that do take arguments to do nothing with Powermockito?
You can find a fully functional example below. Since you didn't post the complete example, I can only assume that you did not annotate the test class with #RunWith or #PrepareForTest because the rest seems fine.
#RunWith(PowerMockRunner.class)
#PrepareForTest({Resource.class})
public class MockingTest{
#Test
public void shouldMockVoidStaticMethod() throws Exception {
PowerMockito.spy(Resource.class);
PowerMockito.doNothing().when(Resource.class, "readResources", Mockito.any(String.class));
//no exception heeeeere!
Resource.readResources("whatever");
PowerMockito.verifyStatic();
Resource.readResources("whatever");
}
}
class Resource {
public static void readResources(String someArgument) {
throw new UnsupportedOperationException("meh!");
}
}
Why go through so much trouble just so that your method does not do anything. Just calling PowerMockito.mockStatic(Resource.class) should replace all static methods in your class with default stubs which basically mean they do nothing.
Unless you do want to change the behavior of your method to actually do something just calling PowerMockito.mockStatic(Resource.class) should suffice. Ofcourse this also means all static methods in the class are stubbed which you need to consider.
If doNothing() isn't working you can hack it a bit using the PowerMockito.doAnswer(). This lets you mock into void methods that are supposed to do something, like setting values, etc. If doNothing() doesn't work, using a blank doAnswer() should work fine.
Example:
PowerMockito.doAnswer(new org.mockito.stubbing.Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return null; //does nothing
}
}).when(mockObject).methodYouWantToDoNothing(args);
Maybe i can't undestand your question, but i believe it's necessary specify what must do
the method, so if you don't specify thenReturn or thenThrow or whatever powerMockito doesn't know what have to do when read your real code, for example:
REAL CODE:
IPager pag;
IPagerData<List<IDeute>> dpag;
pag = new PagerImpl();
pag.setFiles(nombrefilesPaginador);
pag.setInici(1);
dpag = gptService.obtenirDeutes(idSubjecte, idEns, tipusDeute, periode, pag);
Testing real code by mockito:
IPager pag = new PagerImpl();
pag.setInici(1);
pag.setFiles(0);
when(serveiGpt.obtenirDeutes(eq(331225L),
eq(IConstantsIdentificadors.ID_ENS_BASE),
Matchers.any(ETipusDeute.class),
Matchers.any(EPeriodeDeute.class),
eq(pag)))
.thenThrow(new NullPointerException(" Null!"));
If haven't specify the return my test will be fail.
I hope it helps.
I tried doNothing with different variations but nothing worked except the below solution.
#Before
public void setUp(){
obj = new ClassObj (parameters);
//parameters should also include the class obj for which void method is available
}
I have method getAllCustomers inside CustomerService class. Inside this method I call another static method from CustomerDao class.
Now when I am writing the junit for method getAllCustomers inside customerService class, where I want to mock the call to
static method of CustomerDao i.e. getAllCustomers. Here is the brief code snippet of method getAllCustomers inside
CustomerService class. Is it possible to mock the static method call using unitils?
Public static List<CustomerDate> getAllCustomers()
{
//some operations
List<CustomerDate> customers=CustomerDao.getAllCustomers();// static method inside CustomerDao
//some operations
}
Above code is just an example I am trying to put. Please avoid the discussion why these methods are designed as static
methods. That's a separate story .)
I doubt whether it can be achieved with unitils.
But please consider using PowerMock instead which seems to be capable of handling what you need. It can mock static methods,private methods and more (Ref: PowerMock)
This would be a matter of:
Setting up the mock
Calling the mock and expecting some data back
Verifying the end result of your call given your data
So, without really much ado about the static call, here's the way you can set it up in PowerMock:
#RunWith(PowerMockRunner.class)
#PrepareForTest(CustomerDao.class)
public class CustomerTest {
#Test
public void testCustomerDao() {
PowerMock.mockStatic(CustomerDao.class);
List<CustomerDate> expected = new ArrayList<CustomerDate>();
// place a given data value into your list to be asserted on later
expect(CustomerDao.getAllCustomers()).andReturn(expected);
replay(CustomerDao.class);
// call your method from here
verify(CustomerDao.class);
// assert expected results here
}
}