3

I have a legacy class which has a static void method which i need to test:

public class A {

    public static void renameTo()
    {
        String ext = "." + this.fileName + ".backup";
        for (File file : getCSVFile()) {
            f.renameTo(new File(file.getAbsolutePath() + ext));
        }

    public static File[] getAllFiles()
    {
        //logic to read the CSV files from the class path
    }


}

Now I have written a test case for it using PowerMockito which looks like this. Now the issue is, even though the renameTo() is called only, if i call PowerMockito.verifyStatic( Mockito.times(10)) the test still passes

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
@PowerMockIgnore("javax.management.*")
public class ATest {

    @Test
    public void testRenameTo() throws Exception {
        PowerMockito.mockStatic(A.class);
        A.renameTo();
        PowerMockito.verifyStatic( Mockito.times(1));
        //PowerMockito.verifyStatic( Mockito.times(5));//Passes even though the mehod is called only once    
        //PowerMockito.verifyStatic( Mockito.times(10);//Passes even though the mehod is called only once    
    } 
}

Could someone please shed some light into this issue? what I may be doing wrong?

Joe
  • 296
  • 1
  • 7
  • 19

1 Answers1

3

As per the documentation, after the test verifyStatic needs to be called first, then call A.renameTo() to tell it which static method to verify. Example:

// run test
A.renameTo();

// verify interaction
PowerMockito.verifyStatic(A.class, Mockito.times(1));
A.renameTo();
Kiersten Arnold
  • 1,840
  • 1
  • 13
  • 17
  • Hi Chris, If I do that I get this exception : `Wanted but not invoked com.legacy.app.test.A.renameTo(); Actually, there were zero interactions with this mock. at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:262) at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:190)` – Joe Dec 11 '17 at 21:08
  • The exception indicates that Powermock did not record any calls to `A.renameTo()`. Can you post your reworked code? – Kiersten Arnold Dec 11 '17 at 21:54
  • I just put the call to `PowerMockito.verifyStatic(Mockito.times(5))` before callling `renameTo()` `PowerMockito.mockStatic(A.class); PowerMockito.verifyStatic(Mockito.times(5)); A.renameTo();` – Joe Dec 11 '17 at 22:06
  • But if i run it like this as shown below it does call the renameTo method but the verifyStatic still accepts any value for the Mockito.times() and test pases `@SuppressWarnings("static-access") @Test public void testGetCsvFiles() throws Exception { { A spy = PowerMockito.spy(new A()); PowerMockito.verifyStatic(Mockito.times(1)); spy.renameTo((); }` – Joe Dec 11 '17 at 22:09
  • Sorry, I realized I worded my original answer poorly. Edited to be clearer + example. – Kiersten Arnold Dec 11 '17 at 22:32
  • Hi Chris , thanks for pointer . I did what you have suggested but it still takes in any value for Mockito.time(4) `@Test public void testRenameTo() throws Exception { A spy = PowerMockito.spy(new A()); spy.renameTo((); PowerMockito.verifyStatic(A.class,Mockito.times(1)); spy.renameTo((); }` and passes the test instead of checking for times(1) – Joe Dec 12 '17 at 07:54
  • Hmm, I'm not sure how `verifyStatic` interacts with partial mocking (`spy()`). The documentation doesn't say much about it, they only show examples of verifying instance methods of a partial mock. As an aside, it's generally a bad convention to call a static method on an instance of an Object. – Kiersten Arnold Dec 12 '17 at 14:02