Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当Java方法在实体模型后第二次调用时的NPE_Java_Spring_Spring Boot_Junit_Junit5 - Fatal编程技术网

当Java方法在实体模型后第二次调用时的NPE

当Java方法在实体模型后第二次调用时的NPE,java,spring,spring-boot,junit,junit5,Java,Spring,Spring Boot,Junit,Junit5,为了测试服务,我想实施JUnit 5测试: JPA存储库: 服务实施: 测试服务: 因此,当我使用BDDMockito.given…模拟SQL查询riskFilterService.findriskFiltersByTerminalidType…运行代码时,第一次运行的情况很好。 但是在第二次运行binCountryCheckFilterImpl.validateBinCountryCheckFilter()之后我获得代码的NPEriskFilterService.FindriskFilters

为了测试服务,我想实施JUnit 5测试:

JPA存储库:

服务实施:

测试服务:

因此,当我使用
BDDMockito.given…
模拟SQL查询
riskFilterService.findriskFiltersByTerminalidType…
运行代码时,第一次运行的情况很好。 但是在第二次运行
binCountryCheckFilterImpl.validateBinCountryCheckFilter()之后我获得代码的NPE
riskFilterService.FindriskFiltersByTerminalidType….


你知道我如何解决这个问题吗?

很可能测试对象没有使用模拟。由于没有分配依赖项,因此会得到一个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");
    }
}

我不确定BDDMockito是否正确,但在某些框架中,您需要分别模拟连续调用的结果:
.willReturn(riskFiltersList)。willReturn(riskFiltersList)
。很可能测试对象没有使用模拟。由于没有分配依赖项,因此会得到一个NPE。为什么不像终端那样显式地将其注入到主体中呢?模拟在哪里?您在测试中从何处获得riskFilterService?为什么不通过构造函数注入依赖项?事实上,@Nkosi说的。。。其中是
BinCountryCheckFilterImpl-BinCountryCheckFilterImpl=newbincountrycheckfilterimpl(终端)中的
terminal
已定义?@ZeroOne Terminal它只是一个Java对象。它正在工作,但有一种方法我不想将
RiskFilterService
作为构造函数的参数发送,以保持服务的设计干净。还有其他方法吗?@PeterPenzov你怎么能提供你不能注射它们的模拟?好问题-我不知道。其他想法?
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");
    }
}
    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();
        }    
    }
List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "BinCountryCheckFilter");
@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);
    }    
}