我有一个测试,由一个运行测试代码的线程和另一个运行被测系统的线程组成。SuT 包含一些在测试线程中配置的模拟。
我的测试行为是:它在我的本地计算机上执行它应该执行的操作。在我们的构建服务器上,它没有。就我调试的情况而言,问题是,该模拟的行为与配置不同。
所以在我看来,我从测试线程(在某些情况下)的配置没有传播到 sut 线程。
这可能是问题所在吗?在这样的用例中,Mockito不是线程安全的吗?这是一些示例代码,在我的机器上工作,(不幸的是)在我们的构建服务器上工作。
@Test
public void testConcurrency() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(1);
MyService serviceMock = mock(MyService.class);
MyApplication app = new MyApplication(serviceMock);
Future<String> future = executor.submit(app);
when(serviceMock.call()).thenThrow(new RuntimeException("expected exception"));
String result = future.get(1, TimeUnit.SECONDS);
assertNotNull(result);
}
public class MyApplication implements Callable<String> {
private final MyService myService;
public MyApplication(MyService myService) {
super();
this.myService = myService;
}
@Override
public String call() throws Exception {
try {
while(true) {
myService.call();
}
} catch (Exception e) {
return "42";
}
}
}
public static interface MyService {
String call();
}
模拟行为像没有正确配置一样时,我遇到了问题。因此,在其他线程中调用模拟对象的存根方法时,不会调用拦截器。我已经了解 Mockito 在访问其他线程内部的模拟时重置了我的存根。尝试使用以下方法。
@MockBean(reset = MockReset.NONE)
MyService myService
如果您连续进行多次测试,可能会导致问题,但我不确定。如果你有 1 个测试,它会"传播"(不重置)你的模拟行为(存根)到(在)另一个线程中。
传播到其他线程,并且无法通过设计来执行此操作,因为 Mockito 将配置存储在 LocalThread 中。
我不知道在线程之间共享配置的任何方法。
你可以尝试另一个模拟库,例如 EasyMock - 它有另一种设计,并且可能是"线程安全的",在你的罪过中