在 OncePerRequestFilterTest 中调用时,使用 Mockito 指定的模拟 Class 为空

Mocked Class specified with Mockito is null when called in OncePerRequestFilterTest

我有以下过滤器:

@Component
public class OriginFilter extends OncePerRequestFilter {

@Autowired
private CustomJdbcTokenStore tokenStore;

@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain)
        throws ServletException, IOException {
    final String requestTokenHeader = httpServletRequest.getHeader("Authorization");
    
    if (requestTokenHeader != null) {

        if(tokenStore.verifyUserAgentAndHostname(requestTokenHeader.substring(7), httpServletRequest.getHeader("User-Agent"), httpServletRequest.getRemoteAddr())){
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        }else {
            httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
    } else {
        logger.warn("Token is null");
}
}

我有以下测试:

但是在那里,模拟的 tokenStore 始终为 Null,似乎它是从 Class 本身的实例而不是 Mockito 指定的实例中获取的。

@RunWith(MockitoJUnitRunner.class)
public class OFilterTest {

@Mock
CustomJdbcTokenStore tokenStore;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void 
CheckIfFilterPreventsDifferentOriginAccess() throws IOException, ServletException, ParseException {
    Assert.assertNotNull(tokenStore);
    OriginFilter filter = new OriginFilter();
    MockHttpServletRequest mockRequest = new MockHttpServletRequest();

    MockHttpServletResponse mockResponse = new MockHttpServletResponse();

    FilterChain mockFilterChain = Mockito.mock(FilterChain.class);

    when(tokenStore.verifyUserAgentAndHostname(any(),any(),any())).thenReturn(true);

    filter.doFilterInternal(mockRequest, mockResponse, mockFilterChain);
    filter.destroy();

}
}

我做错了什么?

您使用 new 运算符创建了一个 OriginFilter 对象,由于 spring 没有这样做,因此 CustomJdbcTokenStore 应该被注入 OriginFilter手动:

@RunWith(MockitoJUnitRunner.class)
public class OFilterTest {

@InjectMocks
OriginFilter filter;

@Mock
CustomJdbcTokenStore tokenStore;


@Test
public void 
CheckIfFilterPreventsDifferentOriginAccess() throws IOException, ServletException, ParseException {
    Assert.assertNotNull(tokenStore);
    
    MockHttpServletRequest mockRequest = new MockHttpServletRequest();

    MockHttpServletResponse mockResponse = new MockHttpServletResponse();

    FilterChain mockFilterChain = Mockito.mock(FilterChain.class);

    when(tokenStore.verifyUserAgentAndHostname(any(),any(),any())).thenReturn(true);

    filter.doFilterInternal(mockRequest, mockResponse, mockFilterChain);
    filter.destroy();

}

你也不需要 MockitoAnnotations.initMocks(this) 因为你使用 @RunWith(MockitoJUnitRunner.class)