Подтвердить что ты не робот

Отсутствие ветвей при использовании assertTrue вместо assertNull

В Java/Junit мне нужно проверить значение null с некоторым объектом. Существуют различные способы проверки состояния, но я использую assertTrue для большинства своих тестов. Когда я проверяю на nulls в assertTrue, EclEmma утверждает, что он тестирует только одну ветвь.

Когда я разрешаю оператор в переменную вручную (например, устанавливая результат в логическое и передавая его в assertTrue), покрытие кода считается завершенным в утверждении, но не в строке инициализации переменной.

Почему это происходит? Связано ли это с дополнительным байтовым кодом, который Java, по-видимому, добавляет, как упоминалось в http://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions? Любые решения (помимо использования других утверждений assert).

assertTrue:

assertTrue( myObject == null ); //1 of 2 branches

assertTrue:

boolean test = (myObject == null); //1 of 2 branches missing
assertTrue(test); // complete

assertNull:

assertNull( myObject ) //complete;
4b9b3361

Ответ 1

Для большинства булевых выражений компилятор Java генерирует дополнительные ветки в байтовом коде. JaCoCo создает "охват веток" на основе сгенерированного байтового кода, а не на основе исходного кода Java, и, следовательно, отображает дополнительную информацию о охвате веток практически для любого булевого выражения, которое вы использовали.

В вашем коде булево выражение, которое вы используете, myObject == null.

Чтобы вычислить это значение, компилятор Java генерирует код, нажимая два аргумента в стеке, а затем выполняет условный переход, чтобы нажать 1 (true) или 0 (false) в стеке. JaCoCo сообщает об охвате филиалом этого условного перехода.

Таким образом, тот факт, что вы используете myObject == null, запускает описанное вами поведение.

Как и другие примеры, попробуйте следующее:

boolean t = true;
boolean f = false;
boolean result1 = (t && f) || f; // 3 out of 6 missed.
boolean result2 = !t;            // 1 out of 2 missed.

Это может быть полезно, если булево выражение, например, возвращается функцией, которое используется как условие в инструкции if-then-else где-то в другом месте. Хотя в основном это следствие того, как работает компилятор Java, он помогает оценить состояние покрытия (вместо простого охвата веток) исходного кода Java.

Эта функция не слишком хорошо документирована, но вот несколько указателей:

Таким образом, это действительно связано с дополнительным байтовым кодом, но не с конкретными примерами синтетических байтовых компиляторов, для которых предназначены параметры фильтрации.

ПРИМЕЧАНИЕ. Был ли основной РЕДАКТ, поскольку первоначальный ответ был слишком угадан. Спасибо @ira-baxter за хорошее и критичное обсуждение.

Ответ 2

Тот факт, что Эмма относится к условному выражению как "нечто с веткой" для подсчета (ИМХО) покрытия, имеет простое нарушение. Это не условная ветвь.

Мы можем больше спорить об утверждении; если он был определен как "исключение для исключения при утверждении отказа", тогда у него действительно есть условная ветвь; если он определен [как я думаю, я это делаю, я не эксперт по Java), как "прекратить мою программу при отказе от утверждения", то это не действительно ветка. Также неясны вызовы методов; это условные ветки в том смысле, что если вызываемый метод выдает исключение, поток управления не будет продолжать "остальную часть утверждения".

Наш Инструмент Java Test Coverage получает анализ охвата (ответвления) на таких условных "правых".

Ответ 3

Чтобы получить 100% -ный охват кода по логическим методам, выполните следующие

Class RecordService{


    public boolean doesRecordExist(String id){

    return id!=null;

    }


    }

    //Method inside your mock
    @Test
    public boolean testDoesRecordExist(){
    RecordService recordService = mock(RecordService.class);
    when(recordService.doesRecordExists()).thenReturn(
                    anyString()).thenReturn(null);

    }