Тестирование JUnit с использованием powerMockito дает NPE - PullRequest
0 голосов
/ 23 июня 2018

У меня есть класс, для которого я хочу написать тестовый блок Junit.

public class ComparatorUtil {

    public static Map<String, ValueDifference<Object>> compareJsonObject(Object srcObject, Object targetObject)
                throws JsonGenerationException, JsonMappingException, IOException {
        String initialJson = ConverterUtil.convertObjectToJson(srcObject);
        String updatedJson = ConverterUtil.convertObjectToJson(targetObject);
        Gson g = new Gson();
        Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
        Map<String, Object> firstMap = g.fromJson(initialJson, mapType);
        Map<String, Object> secondMap = g.fromJson(updatedJson, mapType);
        Map<String, MapDifference.ValueDifference<Object>> diffMap = Maps.difference(firstMap, secondMap).entriesDiffering();
        return diffMap;
    }
}


public class ConverterUtil {

    public static String convertObjectToJson(Object o)
            throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper mapperObj = new ObjectMapper();
        return mapperObj.writeValueAsString(o);
    }
}

Тестовый блок Junit, написанный мной: -

@RunWith(PowerMockRunner.class)
@PrepareForTest(ConverterUtil.class)
public class ComparatorUtilTest {

    @Before
    public void setUp() {
        PowerMockito.mockStatic(ConverterUtil.class);
    }

    @Test
    public void testValueDiff() throws JsonGenerationException, JsonMappingException, IOException {
        TestObject srcObject = new TestObject();
        srcObject.setColor("white");
        srcObject.setId(1);
        TestObject targetObj = new TestObject();
        targetObj.setColor("white");
        targetObj.setId(1);
        targetObj.setSuffix("AA");
        ComparatorUtil.compareJsonObject(srcObject, targetObj);
        PowerMockito.verifyStatic(VerificationModeFactory.times(2));
        ConverterUtil.convertObjectToJson(srcObject);
        ConverterUtil.convertObjectToJson(targetObj);
    }
}

Когда я запускаюВ тестовом классе я получаю Null Pointer Exception, поскольку initialJson и updatedJson становятся равными нулю.Может кто-нибудь сказать, пожалуйста, где я делаю неправильно?

1 Ответ

0 голосов
/ 23 июня 2018

Здесь так много всего плохого.

  • Вы, похоже, предполагаете, , как использовать PowerMock. Но то, что вы собрали, просто не имеет смысла! Вам нужно создать макет спецификации , используя, например, 'when (). ThenReturn ()'.
  • Значение: недостаточно указать PowerMock, что определенный класс будет подвергнут насмешке. Вы должны сообщить PowerMock о фактических значениях, возвращаемых при вызове этих статических методов.
  • так что начните с чтения хорошего урока сверху вниз. Не используйте PowerMock для собственного кода, вместо этого посмотрите, как учебник решает простую проблему.

Тогда: PowerMock поставляется с определенной стоимостью. Таким образом, вы избегаете его использования. Скорее, вам следует отступить назад и заняться доработкой своего кода, чтобы он мог быть протестирован без необходимости имитировать статические методы. Видите ли, мы говорим о коде, который преобразует некоторый ввод в какой-то вывод. Вы должны быть в состоянии написать производственный и тестовый код, который не требует никакой насмешки для таких ситуаций. Если это вообще необходимо, вы должны использовать такие фреймворки, как Mockito - хороший производственный код можно протестировать без PowerMock.

Более конкретно: почему существует необходимость макетировать статический метод? Кажется, это указывает на то, что ваш ObjectMapper не работает в настройках модульного теста. Это начинается прямо там!

Видите ли, хороший модульный тест для вашего метода преобразования должен просто выглядеть следующим образом:

assertThat(someConverterUnderTest.convert(fineTunedInput), is(expectedOutput));

Вот и все! Вы должны спроектировать ваш конвертер так, чтобы он полностью работал в вашей тестовой среде И тогда все, что нужно для издевательств - это . Другими словами: вы в настоящее время тестируете подробности реализации . Вместо этого вы всегда должны пытаться протестировать публичный контракт ваших методов. Тестирование деталей реализации иногда неизбежно, но, как написано ранее: код, который вы здесь показывает, действительно должен быть протестирован без насмешек.

Тогда: даже когда вам нужны насмешки: методы static мешают вам. Это четкий сигнал о том, что вам не следует использовать static здесь! Вместо этого вы превращаете те элементы, для которых может потребоваться макетирование, либо в параметры, либо в поля тестируемых классов. Потому что тогда вы можете просто вводить макет объектов. Это означает, что вам больше не нужен инструмент PowerMock (ito).

...