Mock Service不使用带有Autowire的构造函数,而是使用Java方法



我想编辑此代码,以便为服务使用mock。此代码运行良好:

@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(Terminals terminal) throws JAXBException, JsonProcessingException {
List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(terminal.getId(), "BinCountryCheckFilter");
}
}

JUnit测试:

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

此代码不起作用:

@Service
public class BinCountryCheckFilterImpl {
@Autowired
@Qualifier("riskFilterService")
private RiskFilterService riskFilterService;
public Response validateBinCountryCheckFilter(Merchants merchant, Contracts contract, Terminals terminal,
PaymentTransaction message, HttpServletRequest request) throws JAXBException, JsonProcessingException {
...........
}
}

由于某种原因,当我运行JUnit测试时,riskFilterService为null。是否有某种方法可以通过JUnit测试正确地实现服务?在我的情况下,我不想从构造函数调用terminal,而是从作为Autowired服务的Java方法validateBinCountryCheckFilter(...)riskFilterService调用。

singleton bean BinCountryCheckFilterImpl不能将每个请求值终端作为字段,即在部署代码时作为构造函数上的参数,但它与JUnit测试一起工作。如果终端值必须作为方法参数传递,那么JUnit代码将不会运行。

你能给我建议吗?

我假设您使用的是JUnit4。最简单的方法是像这样使用MockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class BinCountryCheckFilterImplTest {
@InjectMocks
private BinCountryCheckFilterImpl binCountryCheckFilter;
@Mock
private RiskFilterService riskFilterService;

@Test
public void testBinCountryCheckFilterImpl() {
// test content
}
}

要使用JUnit 5,您需要将@RunWith(MockitoJUnitRunner.class)更改为@ExtendWith(MockitoExtension.class)。当然,使用的任何其他类似@Test的东西也需要来自JUnit5。但是,Mockito@InjectMocks@Mock注释与JUnit4相同。

但是,在使用模拟服务调用构造函数之后,也可以使用Springorg.springframework.test.util.ReflectionTestUtils来设置字段。比起反射,我更喜欢第一种方式,但这更接近您当前的代码。

riskFilterService = Mockito.mock(RiskFilterService.class);
binCountryCheckFilter = new BinCountryCheckFilterImpl();
ReflectionTestUtils.setField(binCountryCheckFilter, "riskFilterService", riskFilterService);

将现有代码更改为:

public class BinCountryCheckFilterImpl {
private final RiskFilterService riskFilterService;
public BinCountryCheckFilterImpl(@Qualifier("riskFilterService") RiskFilterService riskFilterService) {
this.riskFilterService = riskFilterService;
}

public void validateBinCountryCheckFilter(......) throws JAXBException, JsonProcessingException {
.........................
}
}

最新更新