Отмена 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, как показано на рисунке: