Получение NullPointerException при вызове вложенного метода класса Service с использованием mockito - PullRequest
0 голосов
/ 27 декабря 2018

Я пишу контрольные примеры JUnit для своих классов обслуживания.Я создал фиктивные данные, чтобы понять мой сценарий.

@Service
MainClass {
    @Autowired
    C c;
    public void someServiceMethod(){
        ResultClass someResult = c.getResult(string,string, int, int, List<String>,boolean);
    }
}

@Service
public class C {
    @Autowired
    SomeRepository someRepository;
    public ResultClass getResult(string,string, int, int, List<String>,boolean){
        ABC returnSomeClassObject = someRepository.getSomeData(String,int,int);
    }
}

@Test
MainClassTest {
    @MockBean
    SomeRepository someRepository;
    when(someRepository.getSomeData(anyString(),anyInt(),anyInt())).thenReturn(SomeRepository);

    //calling MainClass method
    MainClass.someServiceMethod();
}

Метод getSomeData () класса C, возвращающий объект класса ABC, который имеет значение NULL, и последний устанавливается в другой объект того же типа класса.После установки значения я получаю NULLPointerException, так как ABC равен NULL.У кого-нибудь есть идеи, где я иду не так?

Ответы [ 3 ]

0 голосов
/ 27 декабря 2018

Вы звоните MainClass.someServiceMethod(), что, в свою очередь, вызывает getResult класса C. Вы должны быть насмешливым классом C и использовать when-thenReturn на getResult() класса C, если вы хотите проверить someServiceMethod() класса Main,Autowired не будет работать здесь, так как это модульный тест, и, следовательно, экземпляр C c в классе Main будет нулевым.Примерно так:

@MockBean
C c;
when(c.getResult(anyString(), anyString(),anyInt(),anyInt(), any(List.class), anyBoolean()).thenReturn(someResult);

c.getResult(string,string, int, int, List<String>,boolean);
0 голосов
/ 27 декабря 2018

Итак, прежде всего, нам необходимо уяснить, что именно вы проводите модульное тестирование.Если вы пытаетесь выполнить модульное тестирование someServiceMethod внутри MainClass, то это означает, что вам НЕ следует также тестировать функциональность someRepository.Идея состоит в том, что каждый модульный тест должен проверять только эту единицу кода.Таким образом, для этого нам нужно использовать заглушки в качестве замены для того, что на самом деле происходит, когда вы вызываете методы, принадлежащие другим классам.Затем мы написали бы другой модульный тест только для someRepository.getSomeData(), чтобы подтвердить, что он также работает как задумано.Таким образом, когда позже мы получим сообщение об ошибке, мы точно будем знать, где мы столкнулись с проблемой.

Другая проблема, которую я вижу, заключается в явном несоответствии типов возврата для getResult() в C,Метод говорит, что возвращает ResultClass, но когда вы вызываете getSomeData, вы ожидаете объект ABC.Либо вы не указали детали, в которых вы конвертировали объект обратно в ResultClass, либо это ошибка.Я собираюсь предположить первое, если вы не скажете иначе.

Имея это в виду, давайте напишем наш тест.Вот как я бы написал тест:

@RunWith(SpringRunner.class)
public class MainClassTest {

    @Mock
    C c;

    @InjectMocks
    MainClass mainClass;

    @Test
    public void testSomeServiceMethod {

        ResultClass resultClass = new ResultClass(); //relevant constructor details here, mockbean, etc. you get the idea

        //set any desired data for resultClass here

        Mockito.when(c.getResult(anyString(), anyString(), 
            anyInt(), anyInt(), any(List.class), anyBoolean()))
            .thenReturn(resultClass);

        ResultClass newResult = mainClass.someServiceMethod();

        //relevant test assertions here
    }
}

Как вы можете видеть, мы создаем ResultClass в тесте и сообщаем Mockito, что нужно возвращать его при вызове getResult вместо того, что вы бы сделалиобычно ожидаю, что он вернется.Хотя теперь функциональность может показаться ограниченной, это предпочтительнее, поскольку мы тестируем только MainClass, а не остальные вызовы наших методов.

В дополнение к этому мы можем (и должны) писать тесты для getResult в C и getSomeData в SomeRepository.Я оставлю это вам, чтобы написать эти тесты.

РЕДАКТИРОВАТЬ: случайно опубликовал немного раньше, исправляя сейчас.

0 голосов
/ 27 декабря 2018

Вы не возвращаете ожидаемый объект при написании фиктивного оператора

    @Service
public class C {
    @Autowired
    SomeRepository someRepository;
    public ResultClass getResult(string,string, int, int, List<String>,boolean){
        ABC returnSomeClassObject = someRepository.getSomeData(String,int,int);

        //Your return type should be ResultClass 
        // Where your return statement
        // What is ABC?
    }
}

@Test
MainClassTest {
    @MockBean
    SomeRepository someRepository;
    when(someRepository.getSomeData(anyString(),anyInt(),anyInt())).thenReturn(SomeRepository);
    // Why are you returning SomeRepository, This Should return object of ABC

@MockBean 
ABC mockResultClass
when(someRepository.getSomeData(anyString(),anyInt(),anyInt())).thenReturn(mockResultClass);

    //calling MainClass method
    MainClass.someServiceMethod();
}
...