Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 914
Sam Avatar asked Sep 14 '12 08:09

Sam


People also ask

Why static methods Cannot be mocked?

Mockito allows us to create mock objects. Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

Does PowerMock include Mockito?

Currently PowerMock supports EasyMock and Mockito. When writing unit tests it is often useful to bypass encapsulation and therefore PowerMock includes several features that simplifies reflection specifically useful for testing. This allows easy access to internal state, but also simplifies partial and private mocking.

What is the difference between PowerMock and Mockito?

While Mockito can help with test case writing, there are certain things it cannot do viz:. mocking or testing private, final or static methods. That is where, PowerMockito comes to the rescue. PowerMockito is capable of testing private, final or static methods as it makes use of Java Reflection API.


1 Answers

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.

like image 94
Volodymyr Vronskyi Avatar answered Sep 18 '22 13:09

Volodymyr Vronskyi