Получение NullPointerException, выполняющего модульное тестирование с Mockito - PullRequest
0 голосов
/ 20 апреля 2020

Пожалуйста, не отмечайте его как дубликат, я не могу решить эту проблему. Я пишу модульное тестирование, используя Mockito . При выполнении теста я получаю NullPointerException на @Autowired bean из MainTemplate class.

Код:

public abstract class Template{

  abstract public boolean isEven(String input);

  private String getName(String initial){
    return "INIT"+initial;
  }

  final public void run(String input){
   isEven(input);
   getName(input);

  }
}

Реализация шаблона:

public class MainTemplate extends Template{

 @Autowired
 private UserUtil userUtil;

    @Override
    public boolean isEven(String input){
      return userUtil.getResult(input);  //GETTING NullPointerException here..
    }
}

Конфигурация компонента:

@Configuration
public class BeanConfiguration{
  @Bean
  public Template getBean(){
     return new MainTemplate();
  }
}

@Service
public class Executor{
 @Autowired
 private BeanConfiguration beanConfig;

 public void execute(){
   beanConfig.getBean().run("sample input");
 }

}

Класс модульного тестирования:

@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
public class MainTemplateTest{

  @InjectMocks
  private MainTemplate mainTemplate;

  @Mock
  private UserUtil userUtil;

  @Test
  public void isEvenTest(){

    Mockito.when(userUtil.getResult(anyString())).thenReturn(true);

    mainTemplate.isEven("input string");
  }
}

Я получаю NullPointerException при выполнении вышеуказанного теста. Получение NullPointerException для:

    @Override
    public boolean isEven(String input){
      return userUtil.getResult(input);  //GETTING NullPointerException, while calling from mock method
    }

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Сначала решите, хотите ли вы использовать mockito runner (Junit 4) / extension (Junit 5) или Spring runner / extension (см. @SpringBootTest)

Я считаю, что для этого теста расширение Mockito - это путь к go - тест будет ускоряться и выполняться быстрее и будет меньше agile изменений в конфигурации Spring.

Версия расширения Mockito

  • удалить @ SpringBootTest
  • использовать инжектор конструктора

SpringBootTest версия

  • удалить @RunWith (MockitoJUnitRunner.class)
  • не используйте @InjectMocks, вместо этого используйте @Autowired
  • не используйте @Mock, вместо этого используйте @MockBean
  • Внедрение в поле все еще является запахом кода, сделайте себе одолжение и используйте конструктор впрыск
0 голосов
/ 20 апреля 2020

Вы не можете использовать @InjectMocks для цели, которую вы пытаетесь здесь. Это должно быть изменено, как показано ниже. Вы должны использовать конструктор для того, чтобы использовать @InjectMocks для MainTemplate класса.

Инжекция поля часто является плохим выбором, из-за чего невозможно ввести разные значения для зависимостей.

public class MainTemplate extends Template{    

    private UserUtil userUtil;

    public MainTemplate(UserUtil userUtil){
        super();
        this.userUtil = userUtil;   
    } 


    @Override
    public boolean isEven(String input){
      return userUtil.getResult(input);
    }
}
...