Sam
Sam

Reputation: 131

PowerMock static class does not mock

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

Upvotes: 13

Views: 25732

Answers (2)

Volodymyr Vronskyi
Volodymyr Vronskyi

Reputation: 199

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.

Upvotes: 18

Piohen
Piohen

Reputation: 1530

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.

Upvotes: 4

Related Questions