NPE, когда Java-метод вызывается второй раз после макета - PullRequest
0 голосов
/ 08 ноября 2019

Я хочу реализовать тест JUnit 5 для тестирования сервисов:

Репозиторий JPA:

@Repository
public interface RiskFilterRepository extends JpaRepository<RiskFilters, Integer> {
    .....
}

Сервисный интерфейс:

public interface RiskFilterService {
    ......
}

Реализация сервиса:

@Service
@Qualifier("riskFilterService")
@Transactional
public class RiskFilterServiceImpl implements RiskFilterService {

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private RiskFilterRepository dao;
    ...
}

Сервис для тестирования:

@Service
public class BinCountryCheckFilterImpl {

    @Autowired
    @Qualifier("riskFilterService")
    private RiskFilterService riskFilterService;

    public BinCountryCheckFilterImpl(Terminals terminal) {  
       this.terminal = terminal;
    }

    public void validateBinCountryCheckFilter() throws JAXBException, JsonProcessingException {

        List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(terminal.getId(), "BinCountryCheckFilter");
    }
}

JUnit test

    public class BinCountryCheckFilterImplTest    {

        @Autowired
        private RiskFilterRepository repository;

        @BeforeEach
        public void beforeEachTest() throws IOException {
            MockitoAnnotations.initMocks(this); 
        }

        @Test
        public void testBinCountryCheckFilterImpl() throws JsonProcessingException, JAXBException {
           // this mock is working fine
           BDDMockito.given(riskFilterService.findRiskFiltersByTerminalIdAndType(anyInt(), anyString())).willReturn(riskFiltersList);

           // this mock is working fine - I don't get NPE
           List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "BinCountryCheckFilter");

           // this mock is working fine
           BinCountryCheckFilterImpl binCountryCheckFilterImpl = new BinCountryCheckFilterImpl(terminal);

           // I get NPE here 
           binCountryCheckFilterImpl.validateBinCountryCheckFilter();
        }    
    }

Я получаю ошибку NPE при запускеКод JUnit для этого метода Java validateBinCountryCheckFilter().

List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "BinCountryCheckFilter");

Итак, первый раз, когда я запускаю код с BDDMockito.given...., смоделированный SQL-запрос riskFilterService.findRiskFiltersByTerminalIdAndType.... работает нормально. Но после этого второго раза, когда я запускаю binCountryCheckFilterImpl.validateBinCountryCheckFilter();, я получаю NPE для кода riskFilterService.findRiskFiltersByTerminalIdAndType....

Знаете ли вы, как я могу решить эту проблему?

1 Ответ

1 голос
/ 08 ноября 2019

Скорее всего, испытуемый объект не использует макет. А поскольку зависимость не назначена, вы получаете NPE.

Почему бы явно не внедрить его в субъект с помощью инжектора конструктора, как это делается с помощью терминала.

@Service
public class BinCountryCheckFilterImpl {

    private RiskFilterService riskFilterService;
    private Terminals terminal;

    @Autowired
    public BinCountryCheckFilterImpl(Terminals terminal, RiskFilterService riskFilterService) {  
        this.terminal = terminal;
        this.riskFilterService = riskFilterService;
    }

    public void validateBinCountryCheckFilter() throws JAXBException, JsonProcessingException {

        List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(terminal.getId(), "BinCountryCheckFilter");
    }
}

Таким образом, при тестировании

public class BinCountryCheckFilterImplTest    {

    @Test
    public void testBinCountryCheckFilterImpl() throws JsonProcessingException, JAXBException {
        //Arrange
        RiskFilterService riskFilterService = Mockito.mock(RiskFilterService.class);
        Terminals terminal = Mockito.mock(Terminals.class);

        BDDMockito.given(
            riskFilterService.findRiskFiltersByTerminalIdAndType(anyInt(), anyString()))
            .willReturn(riskFiltersList);

        int expectedInt = 11;
        String expectedString = "BinCountryCheckFilter";

        when(terminal.getId()).thenReturn(expectedInt);

        BinCountryCheckFilterImpl binCountryCheckFilterImpl = 
            new BinCountryCheckFilterImpl(terminal, riskFilterService);

        //Act
        binCountryCheckFilterImpl.validateBinCountryCheckFilter();

        //Assert
        then(riskFilterService)
          .should()
          .findRiskFiltersByTerminalIdAndType(expectedInt, expectedString);
    }    
}
может быть явно введен макет
...