13
public class TestStatic {
    public static int methodstatic(){
        return 3;
    }
}


@Test
@PrepareForTest({TestStatic.class})
public class TestStaticTest extends PowerMockTestCase {

    public void testMethodstatic() throws Exception {
        PowerMockito.mock(TestStatic.class);
        Mockito.when(TestStatic.methodstatic()).thenReturn(5);
        PowerMockito.verifyStatic();
        assertThat("dff",TestStatic.methodstatic()==5);
    }

    @ObjectFactory
    public IObjectFactory getObjectFactory() {
        return new org.powermock.modules.testng.PowerMockObjectFactory();
    }
}

The exception :

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.

I am running it through Intellij, the legacy code has plenty of methods...

Someone has and idea, I went through the official tuto, no mean to make this simple test working

Sam
  • 131
  • 1
  • 1
  • 3

3 Answers3

18

I found the solution for such issue in my case, want to share it with you:

If I called the mocked method in the test class:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Calendar.class)
public class TestClass {
  @Test
  public void testGetDefaultDeploymentTime()
    PowerMockito.mockStatic(Calendar.class);
    Calendar calendar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 8);
    calendar.set(Calendar.MINUTE, 0);
    when(Calendar.getInstance()).thenReturn(calendar);
    Calendar.getInstance();
  }
}

it worked just fine. But when I rewrited test so it called Calendar.getInstance() in another class it used the real Calendar method.

@Test
public void testGetDefaultDeploymentTime() throws Exception {
  mockUserBehaviour();
  new AnotherClass().anotherClassMethodCall();    // Calendar.getInstance is called here
}

So, as a solution I added AnotherClass.class to @PrepareForTest and it works now.

@PrepareForTest({Calendar.class, AnotherClass.class})

It seems PowerMock needs to know where mocked static method will be called.

  • This does not seem like a static method calls though, you are calling the methods on the object as far as I can see!!! – electronix384128 Mar 12 '16 at 00:00
  • Still doesn't work for me .... i am trying to make `BDDMockito.given(Files.createDirectories(any(Path.class))).willThrow(new IOException());` but no luck it still uses the original Files.createDirectories in the original class... :( – GOXR3PLUS Nov 20 '18 at 15:07
  • This actually also worked for us +1pt – Kibonge Murphy Feb 17 '23 at 15:12
4

I took a look at my tests of legacy code and I can see is that you call PowerMockito.mock(TestStatic.class) instead of PowerMockito.mockStatic(TestStatic.class). Doesn't matter if you use PowerMockito.when(...) or Mockito.when(...), because the first one simply delegates to the second one.

One more remark: I understand that maybe you have to test a legacy code. Maybe you could do that in JUnit4 style, just not to produce a legacy tests? The example mentioned by Brice is a good one.

Piohen
  • 1,514
  • 15
  • 23
0

Take a look at this Answer : Mocking Logger and LoggerFactory with PowerMock and Mockito

Also you shouldn't use Mockito.when if you want to stub static calls but PowerMockito.when.

Statics are a testability nightmare, you avoid that as much as possible, and rework your design in order to not use statics anymore or to not have to use PowerMock tricks to be able to test your production code.

Vampire
  • 35,631
  • 4
  • 76
  • 102
bric3
  • 40,072
  • 9
  • 91
  • 111
  • Thanks, yeah you do not choose the legacy code :), but you can refactor... ill do static mock and apply mockable pattern. – Sam Sep 14 '12 at 09:52
  • Agreed legacy code is a pain, PowerMock is indeed powerful in theses cases :) – bric3 Sep 14 '12 at 11:35
  • 1
    This just isn't true: "Also you shouldn't use `Mockito.when` if you want to stub static calls". The PowerMockito usage page uses `Mockito.when` in its example code. – ach Oct 31 '14 at 20:06