java - 使用 doReturn 为 Spring Service 实现 JUnit 测试

标签 java junit mockito junit5

我想通过使用doReturn来实现此Spring服务的JUnit测试模拟请求:

        @Service
        public class BinCountryCheckFilterImpl {

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

            @Autowired
            @Qualifier("binlistsService")
            private BinlistsService binlistsService;

            public BinCountryCheckFilterImpl() {        
            }

            public PaymentResponse validateBinCountryCheckFilter(Merchants merchant, Contracts contract, Terminals terminal,
                      PaymentTransaction message, HttpServletRequest request) throws JAXBException, JsonProcessingException {

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

                     Optional<BinLists> db_bin_list = binlistsService.findByName(billing_address_country);
             }
       }

我尝试了这个 JUnit 测试:

public class BinCountryCheckFilterImplTest {
    Terminals terminal = null;

    @InjectMocks
    private BinCountryCheckFilter binCountryCheckFilter;

    private BinlistsService binlistsService = Mockito.mock(BinlistsService.class);  
    private RiskFilterService riskFilterService = Mockito.mock(RiskFilterService.class);

    @Mock
    List<RiskFilters> riskFiltersList = null;

    Optional<BinLists> binList = null;

    @BeforeEach
    public void beforeEachTest() throws IOException {

        MockitoAnnotations.initMocks(this);             
        riskFiltersList = new ArrayList<RiskFilters>(); 

        RiskFilters filter = new RiskFilters();
        riskFiltersList.add(filter);    

        BinLists binLists = new BinLists();
        binList = Optional.of(binLists);
        terminal = new Terminals();
        terminal.setId(11);
    }

    @Test
    public void testBinCountryCheckFilterImpl() throws JsonProcessingException, JAXBException {

        //      when(riskFilterService.findRiskFiltersByTerminalIdAndType(anyInt(), anyString())).thenReturn(riskFiltersList);      

doReturn(riskFiltersList).when(riskFilterService).findRiskFiltersByTerminalIdAndType(anyInt(), anyString());
        when(binlistsService.findByName(anyString())).thenReturn(binList);

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

        Optional<BinLists> bin = binlistsService.findByName("US");

        BinCountryCheckFilterImpl binCountryCheckFilterImpl = new BinCountryCheckFilterImpl();

        binCountryCheckFilterImpl.validateBinCountryCheckFilter(merchant, contract, terminal, authorizeTransactiontMockup(), request);
    }

当我尝试使用 doReturn 模拟请求时,代码工作正常.....但是当我调用实际的 Spring 服务以便在服务 Java 类 BinCountryCheckFilterImpl 的这一行使用 NPE 对其进行测试时,它失败了:

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

我如何模拟这个 SQL 查询请求?

编辑:我尝试了这个最小的示例,但它现在可以工作:

@Service
public class BinCountryCheckFilterImpl {

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

    @Autowired
    @Qualifier("binlistsService")
    private BinlistsService binlistsService;


    @Autowired
    public BinCountryCheckFilterImpl(
            @Qualifier("binlistsService") BinlistsService binlistsService,
            @Qualifier("riskFilterService") RiskFilterService riskFilterService) {
        this.binlistsService = binlistsService;
        this.riskFilterService = riskFilterService;
    }

    public BinCountryCheckFilterImpl() {        
    }

    public void validateBinCountryCheckFilter() throws JAXBException, JsonProcessingException {
        List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "BinCountryCheckFilter");   
    }
}

JUnit 测试:

public class BinCountryCheckFilterImplTest {

    @Mock
    private BinCountryCheckFilterImpl binCountryCheckFilter;

    private BinlistsService binlistsService = Mockito.mock(BinlistsService.class);

    @Mock
    private RiskFilterService riskFilterService = Mockito.mock(RiskFilterService.class);

    @Mock
    List<RiskFilters> riskFiltersList = null;

    Optional<BinLists> binList = null;
    Terminals terminal = null;

    @BeforeEach
    public void beforeEachTest() throws IOException {

        MockitoAnnotations.initMocks(this); 

        riskFiltersList = new ArrayList<RiskFilters>(); 

        RiskFilters filter = new RiskFilters();
        filter.setId(1);

        riskFiltersList.add(filter);    

        BinLists binLists = new BinLists();
        binLists.setId(1);

        binList = Optional.of(binLists);

    }

    @Test
    public void testBinCountryCheckFilterImpl() throws JsonProcessingException, JAXBException {

        binCountryCheckFilter = 
                  new BinCountryCheckFilterImpl(binlistsService, riskFilterService);

        doReturn(riskFiltersList).when(riskFilterService).findRiskFiltersByTerminalIdAndType(anyInt(), anyString());


        BinCountryCheckFilterImpl binCountryCheckFilterImpl = new BinCountryCheckFilterImpl();

        binCountryCheckFilterImpl.validateBinCountryCheckFilter();
    }    
}

我在同一行再次得到 NPE。

最佳答案

你可以调试它来检查是否有riskFilterService的实例吗?

我认为问题是因为您的类 BinCountryCheckFilterImpl 实际上并未接收模拟。

您有两种选择来解决此问题:

  1. 您使用 Spring Context,spring 会 @Autowire 模拟,但从我的角度来看,这不再是单元测试;

  2. 您可以更改实例化组件的方式,使用构造函数 Autowiring 依赖项:

@服务 公共(public)类 BinCountryCheckFilterImpl {

private RiskFilterService riskFilterService;

private BinlistsService binlistsService;

@Autowired
public BinCountryCheckFilterImpl(
        @Qualifier("binlistsService") BinlistsService binlistsService,
        @Qualifier("riskFilterService") RiskFilterService riskFilterService) {
    this.binlistsService = binlistsService;
    this.riskFilterService = riskFilterService;
}

然后,在单元测试中,只需使用模拟服务实例化要测试的类,例如:

Optional<BinLists> binList = null;

@BeforeEach
public void beforeEachTest() throws IOException {

    MockitoAnnotations.initMocks(this);             
    riskFiltersList = new ArrayList<RiskFilters>(); 

    RiskFilters filter = new RiskFilters();
    riskFiltersList.add(filter);    

    BinLists binLists = new BinLists();
    binList = Optional.of(binLists);
    terminal = new Terminals();
    terminal.setId(11);

    binCountryCheckFilter = 
      new BinCountryCheckFilterImpl(riskFilterService, binlistsService);
}

并且您将不需要 @InjectMocks 注释。

编辑:添加完整解决方案

@Service
public class BinCountryCheckFilterImpl {

    private RiskFilterService riskFilterService;

    private BinlistsService binlistsService;


    @Autowired
    public BinCountryCheckFilterImpl(
            @Qualifier("binlistsService") BinlistsService binlistsService,
            @Qualifier("riskFilterService") RiskFilterService riskFilterService) {
        this.binlistsService = binlistsService;
        this.riskFilterService = riskFilterService;
    }

    public BinCountryCheckFilterImpl() {        
    }

    public void validateBinCountryCheckFilter() throws JAXBException, JsonProcessingException {
        List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "BinCountryCheckFilter");   
    }
}

测试:

public class BinCountryCheckFilterImplTest {

    private BinCountryCheckFilterImpl binCountryCheckFilter;

    @Mock
    private BinlistsService binlistsService;

    @Mock
    private RiskFilterService riskFilterService;

    @Mock
    List<RiskFilters> riskFiltersList = null;

    Optional<BinLists> binList = null;
    Terminals terminal = null;

    @BeforeEach
    public void beforeEachTest() throws IOException {

        MockitoAnnotations.initMocks(this); 

        riskFiltersList = new ArrayList<RiskFilters>(); 

        RiskFilters filter = new RiskFilters();
        filter.setId(1);

        riskFiltersList.add(filter);    

        BinLists binLists = new BinLists();
        binLists.setId(1);

        binList = Optional.of(binLists);

        binCountryCheckFilter = 
                  new BinCountryCheckFilterImpl(binlistsService, riskFilterService);

    }

    @Test
    public void testBinCountryCheckFilterImpl() throws JsonProcessingException, JAXBException {
        doReturn(riskFiltersList).when(riskFilterService).findRiskFiltersByTerminalIdAndType(anyInt(), anyString());
        binCountryCheckFilterImpl.validateBinCountryCheckFilter();
    }    
}

关于java - 使用 doReturn 为 Spring Service 实现 JUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58651330/

相关文章:

Mockito 在 junit 中的事件

java - 如何在Spring Boot中用自己的mock替换BeanFactory中的bean?

java - Java 中的正则表达式点运算符似乎总是贪婪地工作

java - Spring的contextConfigLocation xml和Controller类是如何连接的?

java - 使用java自动化实时数据

java.lang.NoSuchMethodError : 'void org.springframework.util.Assert.state(boolean, java.util.function.Supplier)' 错误

java - Mockito 方法返回 null

java - 莫基托。验证方法参数

java - int[] 到 List<int> 的类型映射

java - 在 OSX/Unix 上设置额外的 Tomcat 服务器