我有一个类,由于接口的强制实现,我不能轻易地使用依赖注入来模拟 - 简而言之,因为我将使用Whitebox而我在这里的关注与设计无关,而是它只是想弄清楚如何正确地“撕下”"由Whitebox引起的行为。忍受我一秒钟,我会给你更多细节 - 这是主要的假人类:
public class Dummy implements MandatoryInterface {
private static final Logger logger = Logger.getLogger(MethodHandles.lookup().lookupClass());
private final ObjectMapper mapper = new ObjectMapper();
@Override
public Object convertArgumentToJson(Object arg) {
if (arg != null) {
try {
return mapper.writeValueAsString(arg);
} catch (IOException e) {
// doSomething();
logger.error("Error tracking request", e);
}
}
return null;
}
}
假设我想要涵盖在此处发生异常时会发生什么,我看到的唯一方法是使用 Whitebox.setInternalState 。在这里测试:
public class DummyTest {
private Dummy dummy = new Dummy();
@Test
public void testA() throws IOException {
final ObjectMapper mock = Mockito.mock(ObjectMapper.class);
Whitebox.setInternalState(dummy, "mapper", mock);
Mockito.when(mock.writeValueAsString(Mockito.any()))
.thenThrow(new IOException());
Assert.assertNull(dummy.convertArgumentToJson("testA"));
}
@Test
public void testB() {
Assert.assertNotNull(dummy.convertArgumentToJson("testB"));
}
}
正如您所看到的,我无法将Dummy类中的映射器定义为静态,因为Whitebox(它不会起作用)。 话虽如此,在执行 testA()之后,我们已经模拟了映射器:
问题是:当执行 testB 时,我不再需要模拟 - 它应该是最初包含在Dummy中的旧实例化ObjectMapper。但看起来是什么:
现在,我的问题:
撤消
的正确方法是什么 Whitebox.setInternalState(dummy, "mapper", mock);
P.S。:我考虑过像这样使用tearDown():
@AfterMethod
public void tearDown(){
Whitebox.setInternalState(dummy, "mapper", originalState);
}
然而,在这种情况下,我的pitest(变异测试)会认为我没有覆盖ObjectMapper的初始化,所以:有没有办法只需要在没有手动设置的情况下撤消其余测试的Whitebox旧的?
对于长篇描述和提前感谢,我们深表歉意。
此致
答案 0 :(得分:0)
对不起伙计们,我设法得到了它。
万一其他人可能面临同样的问题,答案比我想象的要容易。
private static final String MAPPER_DESC = "mapper";
private ObjectMapper originalMapper;
@BeforeMethod
public void init() {
MockitoAnnotations.initMocks(this);
originalMapper = (ObjectMapper) Whitebox.getInternalState(converter, MAPPER_DESC);
}
@AfterMethod
public void tearDown() {
Whitebox.setInternalState(converter, MAPPER_DESC, originalMapper);
}
然后 testA 和 testB 可以保持相同的代码。并且变异测试仍然会覆盖ObjectMapper属性声明,如图所示: