模拟服务不使用构造函数与 Autowire 但使用 Java 方法
Mock Service without using constructor with Autowire but use Java method
我想编辑此代码以使用模拟服务。此代码运行良好:
@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
in null。有什么方法可以正确地使用 JUnit 测试实现服务吗?
在我的例子中,我不想从构造函数调用 terminal
,而是从 Java 方法 validateBinCountryCheckFilter(...)
和 riskFilterService
作为自动装配服务。
单例 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
之类的任何其他内容也需要来自 JUnit 5。但是,Mockito @InjectMocks
和 @Mock
注释与 JUnit 4 相同。
但是,您也可以在使用模拟服务调用构造函数后使用 Spring org.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 {
.........................
}
}
我想编辑此代码以使用模拟服务。此代码运行良好:
@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
in null。有什么方法可以正确地使用 JUnit 测试实现服务吗?
在我的例子中,我不想从构造函数调用 terminal
,而是从 Java 方法 validateBinCountryCheckFilter(...)
和 riskFilterService
作为自动装配服务。
单例 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
之类的任何其他内容也需要来自 JUnit 5。但是,Mockito @InjectMocks
和 @Mock
注释与 JUnit 4 相同。
但是,您也可以在使用模拟服务调用构造函数后使用 Spring org.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 {
.........................
}
}