PowerMock 影响其他测试中的测试 类

PowerMock affecting tests in other test classes

我正在使用 PowerMock 来测试 InterruptedException 情况下的错误处理。不幸的是,这些测试有时似乎对其他测试有一些副作用 classes:我在一个测试 class 中配置的模拟在另一个测试 class 中似乎仍然存在。我将以下示例简化为基本行以产生副作用。

假设我们有一个 class 来测试:

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

还有一项测试 class 使用 PowerMock 测试私有方法:

@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);
  }
}

当我现在创建另一个测试时 class(在第一个测试之后执行),如下所示:

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

我立即得到以下异常:

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

如果我再次删除第一个 class 中的模拟,一切都会按预期进行。

到目前为止,我假设不同的测试 classes 应该不会相互影响。然而,在这个例子中,情况似乎是这样。这是我不知道的 PowerMock 的某些功能吗?如果是这样,有什么办法可以防止这种情况发生吗?

Thread.currentThread().interrupt() 可能会阻止 JUnit/PowerMock 执行某种 "cleanup" 吗?

我正在使用以下依赖项:

看来你是对的,因为第一个测试正在影响第二个,如果它们是套件的一部分的话。看着 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.

如果这些是单元测试,您想模拟对 Thread.currentThread().interrupt() 的调用。实际上调用中断会破坏 "unit tests"

的 "unit" 部分

您正在设置导致睡眠被中断的中断标志。这与模拟无关,因为这个简单的例子显示了相同的行为:

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

如果您的测试使用中断,您可能需要添加:

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

参加基础测试 class。