简体   繁体   中英

PowerMock affecting tests in other test classes

I'm using PowerMock to test the error handling in case of an InterruptedException . Unfortunately, these test sometime seem to have some side effects on other test classes: Mocks that I configure in one test class seem to be still alive in another test class. I stripped down the following example to the essential lines to just produce the side effect.

Lets assume we have one class to test:

public class SomeClass {
  private void someMethod(Future<Document> future) {
    try {
      future.get();
    } catch (Exception e) {
      Thread.currentThread().interrupt();
    }
  }
}

And one test class using PowerMock to test a private method:

@RunWith(PowerMockRunner.class)
public class DispatcherTest {

  @Test
  public void simpleTest() throws Exception {
    Future<Object> futureMock = PowerMockito.mock(Future.class);
    PowerMockito.when(futureMock.get()).thenThrow(new InterruptedException());
    SomeClass dispatcher = PowerMockito.mock(SomeClass.class);
    Whitebox.invokeMethod(dispatcher, "someMethod", futureMock);
  }
}

When I now create another test class (that is executed after the first one) like this:

public class SimpleTest {
  @Test
  public void simpleTest() throws InterruptedException {
    Thread.sleep(100);
  }
}

I immediately get the following exception:

java.lang.InterruptedException: sleep interrupted
  at java.lang.Thread.sleep(Native Method)
  at de.mocktest.SimpleTest.shouldSleep(SimpleTest.java:9)

If i remove the mock in the first class again, everything works as expected.

Until now, I assumed that different test classes should not affect each other. In this example it, however, seems to be the case. Is that some feature of PowerMock I'm just not aware of? And if so, is there any way to prevent that?

Could Thread.currentThread().interrupt() probably prevent JUnit/PowerMock from performing some kind of "cleanup"?

I'm using the following dependencies:

  • JUnit 4.12
  • Mockito 1.10.19
  • PowerMock 1.6.3

It seems you are correct as the first test is affecting the second, if they are part of a suite. Looking at this question , if you call interrupt before sleep, you can get an exception if the interrupted status has not been cleared. The interrupted status is cleared (and interrupt exception thrown) on a number of method calls .

If these are unit tests, you want to mock the call to Thread.currentThread().interrupt() . Actually calling interrupt would break the "unit" part of "unit tests"

You are setting the interrupt flag which is causing sleep to be interrupted. This does not have to do with the mocks, as this simple example shows the same behaviour:

public class SimpleTest {
    @Test
    public void test1() {
        Thread.currentThread().interrupt();
    }
    @Test
    public void test2() throws InterruptedException {
        Thread.sleep(100);
    }
}

If your tests use interrupt, you may want to add:

@Before
public void before() {
    // clear the interrupted flag
    Thread.interrupted();
}

to your base test class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM