簡體   English   中英

模型后第二次調用 Java 方法時的 NPE

[英]NPE when Java method is called second time after mockup

我想執行 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 測試

    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();
        }    
    }

當我為此 Java 方法validateBinCountryCheckFilter()運行 JUnit 代碼時出現 NPE 錯誤。

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

因此,當我第一次使用BDDMockito.given....運行代碼時,模擬的 SQL 查詢riskFilterService.findRiskFiltersByTerminalIdAndType....工作正常。 但是在我第二次運行binCountryCheckFilterImpl.validateBinCountryCheckFilter();之后我得到代碼riskFilterService.findRiskFiltersByTerminalIdAndType....

你知道我該如何解決這個問題嗎?

很可能被測對象沒有使用模擬。 而且由於沒有分配依賴關系,因此您將獲得 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);
    }    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM