Как имитировать логическую переменную, имеющую несколько условий && с вложенными методами? MOCKITO ДЛЯ ИСПЫТАНИЯ БЛОКА - PullRequest
0 голосов
/ 04 августа 2020

Итак, моя проблема такая? У меня есть частный метод, в котором я передаю переменную a, и это условия для того, чтобы логическая переменная была истинной. У меня есть класс B с getB(), класс C с getC() методами, интерфейс D с getD() методом с типом возвращаемого значения long. У меня есть другой метод (stati c boolean isE()), в котором я передаю локальную переменную f и вызываю метод getG() из другого класса H.

Как издеваться эти значения для модульного тестирования с использованием Mockito, чтобы моя логическая переменная check стала true.

boolean check = a != null
                && a.getB().getC().getD() >= 0
                && !isE(f.getG()))

Ответы [ 3 ]

0 голосов
/ 04 августа 2020

Во-первых, вы не можете тестировать частные методы с JUnit / Mockito из коробки.

Во-вторых, ваше именование сбивает с толку: вы говорите «B с getB()» и затем вы вызываете параметр a (для a.getB()). B.getB() должен возвращать C, а не B, так как тогда getC() вызывается на нем. И вы говорите «C с getC()», а также «вложенные методы». Кроме того, D.getD() возвращает не объект типа D, а long. Я адаптировал все это в соответствии с тем, что, как я думал, вы планировали. 1023 *

class C {
    D getD() {
        return null;
    }
}
interface D {
    default long getLong() {
        return -1;
    }
}
class E extends G {
}
class F {
    G getG() {
        return new E();
    }
}
class G {
}

Тестируемый класс

import static java.lang.System.out;

class Clazz {

    static boolean isE( final Object o ) {
        return o instanceof E;
    }

    F f;

    boolean method( final B b, final String origin ) {
        out.printf( "---- %s%nb=%s%n", origin, b );
        out.printf( "long=%s, original: %s%nisE=%s, original: %s%n",
                b != null ? String.valueOf( b.getC().getD().getLong() ) : "<not invoked>",
                ( new D() {} ).getLong(),
                isE( f.getG() ), Clazz.isE( new F().getG() ) );

        final boolean check = b != null
                && b.getC().getD().getLong() >= 0
                && ! isE( f.getG() );

        out.printf( "check=%s%n", check );
        return check;
    }
}

Тестовый класс

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.openMocks;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

class ClazzTest {

    @InjectMocks
    Clazz clazz = new Clazz();

    @Mock private B b;
    @Mock private C c;
    @Mock private D d;
    @Spy private F f;

    @BeforeEach
    void beforeEach() {
        openMocks( this );
    }

    @Test
    void testMocked() {
        when( b.getC() ).thenReturn( c );
        when( c.getD() ).thenReturn( d );
        when( d.getLong() ).thenReturn( 0 );
        when( f.getG() ).thenReturn( new G() );

        assertTrue( clazz.method( b, "mocked" ) );
        assertFalse( clazz.method( null, "mocked" ) );
    }

    @Test
    void testOriginal() {
        assertFalse( clazz.method( null, "original" ) );
        assertThrows( NullPointerException.class, () -> clazz.method( new B(), "original" ) );
        System.out.println( "expected <NPE thrown>" );
    }
}

Выход

---- mocked
b=b
long=0, original: -1
isE=false, original: true
check=true
---- mocked
b=null
long=<not invoked>, original: -1
isE=false, original: true
check=false
---- original
b=null
long=<not invoked>, original: -1
isE=true, original: true
check=false
---- original
b=igb.so.B@8dfe921
<expected NPE thrown>
0 голосов
/ 04 августа 2020

Щелкните правой кнопкой мыши по всему условию -> Извлечь в новый метод

Это создаст новый метод. Вы можете издеваться, как считаете нужным, и использовать это в своих тестах.

0 голосов
/ 04 августа 2020

надо издеваться на внешний звонок. если вы пишете тесты для класса A..mock все экземпляры класса B или класса C .. например:

when (instance_of_class_b.someMethodOnClassB ()). then (return true или false).

Mocking означает имитацию внешних вызовов из класса. Вы не можете имитировать частные вызовы внутри одного класса, не имеет значения.

Дополнительную информацию можно найти в библиотеке Mockito

...