Отмена Whitebox.setInternalState в @AfterMethod без установки исходного состояния

У меня есть класс, который я не могу с легкостью использовать инъекцией зависимостей для имитации из-за обязательной реализации интерфейса - в двух словах, по этой причине я буду использовать Whitebox, и моя проблема здесь не связана с дизайном, а просто выяснить, как правильно "tearDown" поведение, вызванное 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 я больше не хочу использовать макет - это должен быть старый экземплярный экземпляр ObjectMapper, изначально включенный в Dummy. Но что появляется:

Теперь мой вопрос:

Как правильно отменить

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

PS: я рассмотрел использование tearDown() следующим образом:

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

Однако в этом сценарии мой питест (тест на мутацию) будет учитывать, что я не рассматриваю инициализацию ObjectMapper, поэтому: есть ли способ просто отменить Whitebox для остальных тестов, не устанавливая вручную старый?

Извините за длинное описание и заранее спасибо.

С Уважением,

1 ответ

Решение

Извините, ребята, мне удалось это иметь.

Просто на тот случай, если кто-то еще может столкнуться с тем же вопросом, ответ был проще, чем я предполагал.

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, как показано на рисунке: введите описание изображения здесь

Другие вопросы по тегам