18

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?

Anakin001
  • 1,226
  • 2
  • 14
  • 30

5 Answers5

26

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!");
    }
}
Abhishek
  • 920
  • 13
  • 23
Morfic
  • 15,178
  • 3
  • 51
  • 61
  • Thanks, that was it, I forgot to annotate with @PrepareForTest (my other example was working because there I remembered to annotate). – Anakin001 Apr 11 '14 at 05:35
  • No problem, happened to me a couple of time and I lost a few hours trying to figure it out – Morfic Apr 11 '14 at 07:34
  • @Anakin001 : What if the **"readResources"** method is private and non-static in this case? – NIKHIL CHAURASIA Jan 13 '17 at 09:49
  • @NIKHILCHAURASIA It's pretty much similar. You can see a full example [here](https://github.com/powermock/powermock/blob/master/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/privatemocking/PrivateInstanceMockingTest.java). What did you try and what problems did you get? – Morfic Jan 13 '17 at 11:36
  • The line PowerMockito.doNothing()... it calls readResources method as well while mocking method. anyone knows how to stop it? – Jugal Panchal Aug 15 '18 at 18:37
  • @JugalPanchal you should ask a new question and provide a [sscce](http://sscce.org) so people can investigate – Morfic Aug 16 '18 at 10:08
  • @JugalPanchal I'm having this exact issue, did you open a question about this? I've opened three, none of which have been even attempted to answer. – notAChance Nov 07 '18 at 10:28
  • @xeon48 can you link them here? I looked over your profile but didn't find any unanswered questions related to powermockito. – Morfic Nov 07 '18 at 15:11
  • I deleted them (shameful I know) - I found out though that my problem was I needed to pass `any()` instead of my mocked objects to my `MemberMatcher.method` method. Hope that helps people. (The `MemberMatcher.method` method allows one to define the `overloaded` (`private` if needed) method you want to call). – notAChance Nov 07 '18 at 15:30
  • @JugalPanchal Hey did you guys find out the way that if we are mocking a private void method, it still gets called when invoking the test method, so what's the way to stop that? – striker Jun 28 '22 at 16:41
7

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.

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
4

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);
Walls
  • 3,972
  • 6
  • 37
  • 52
  • 1
    It works, thanks, but the problem was that I had forgotten to annotate with @PrepareForTest, like Grove suggested. Nevertheless, great answer and I will keep it in mind for the future (I didn't know about doAnswer). – Anakin001 Apr 11 '14 at 05:38
0

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.

ZaoTaoBao
  • 2,567
  • 2
  • 20
  • 28
  • 1
    Thanks for your answer. I can't return anything since my method returns void. Also, I don't want to throw an exception. I just want the method to do nothing. – Anakin001 Apr 10 '14 at 08:45
0

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
}
Suresh
  • 1,491
  • 2
  • 22
  • 27