使用doReturn实现Spring Service的JUnit测试



我想通过使用doReturn模拟请求来实现这个Spring Service的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 Service以便在服务Java类BinCountryCheckFilterImpl:的这一行用NPE测试它时,它失败了

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

如何模拟此SQL查询请求?

EDIT:我尝试了这个最小的例子,但它现在起作用了:

@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实际上并没有接收到mock。

你有两个选项来解决这个问题:

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

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

@服务公共类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();
}    
}

最新更新