0

我有一个类,由于接口的强制实现,我不能轻易地使用依赖注入来模拟 - 简而言之,因此我将使用 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 类中的映射器定义为静态的。话虽如此,在执行testA()之后,我们对映射器进行了模拟:

在此处输入图像描述

问题是:在执行testB时,我不再想要模拟 - 它应该是最初包含在 Dummy 中的旧实例化 ObjectMapper。但是出现了什么:

在此处输入图像描述

现在,我的问题:

撤消的正确方法是什么

 Whitebox.setInternalState(dummy, "mapper", mock);

PS:我考虑过使用这样的 tearDown() :

@AfterMethod
public void tearDown(){
    Whitebox.setInternalState(dummy, "mapper", originalState);
}

但是,在这种情况下,我最讨厌(突变测试)会认为我没有涵盖 ObjectMapper 的初始化,所以:有没有办法在不手动设置旧测试的情况下撤消其余测试的白盒?

抱歉,描述太长了,在此先感谢。

问候,

4

1 回答 1

3

对不起,伙计们,我设法拥有它。

以防万一其他人可能面临同样的问题,答案比我想象的要容易。

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

那么testAtestB可以保持相同的代码。并且突变测试仍将覆盖 ObjectMapper 属性声明,如图所示: 在此处输入图像描述

于 2018-06-11T09:33:50.897 回答