模拟服务不使用带有 Autowire 的构造函数但使用 Java 方法

Pet*_*zov -1 java junit spring spring-boot junit5

我想编辑此代码以使用模拟服务。这段代码工作正常:

@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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }    
}
Run Code Online (Sandbox Code Playgroud)

此代码不起作用:

    @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 {
               ...........

    }

}
Run Code Online (Sandbox Code Playgroud)

出于某种原因riskFilterService,当我运行 JUnit 测试时为 null。有什么方法可以通过 JUnit 测试正确实现服务吗?就我而言,我不想terminal从构造函数调用,而是从 Java 方法validateBinCountryCheckFilter(...)riskFilterServiceAutowired 服务调用。

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

请你给点建议好吗?

DCT*_*TID 6

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

@RunWith(MockitoJUnitRunner.class)
public class BinCountryCheckFilterImplTest {

    @InjectMocks
    private BinCountryCheckFilterImpl binCountryCheckFilter;

    @Mock
    private RiskFilterService riskFilterService;


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

}
Run Code Online (Sandbox Code Playgroud)

要使用JUnit 5,你会改变@RunWith(MockitoJUnitRunner.class)@ExtendWith(MockitoExtension.class)。当然,其他类似的东西@Test也需要来自 JUnit 5。但是,Mockito@InjectMocks@Mock注释与 JUnit 4 相同。

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

riskFilterService = Mockito.mock(RiskFilterService.class);
binCountryCheckFilter = new BinCountryCheckFilterImpl();
ReflectionTestUtils.setField(binCountryCheckFilter, "riskFilterService", riskFilterService);
Run Code Online (Sandbox Code Playgroud)