【问题标题】:JUnit testing with mockito使用 mockito 进行 JUnit 测试
【发布时间】:2019-09-24 17:12:53
【问题描述】:

我有这个过滤器类,在使用 junit 进行测试时需要尽可能高的代码覆盖率。

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String userId= request.getHeader(Constants.USER_ID);

    if (StringUtils.isEmpty(userId)) {
        LOGGER.error("User Id is missing in request header.");
        isAuthorized = false;
    } 

    if (!isAuthorized) {
        LOGGER.warn("Authorization failed: User ID =[{}] is not authorized to access.", userId);
        response.setContentType("text/html; charset=UTF-8");
        response.getWriter().write(errorMsg);
    } else {
        filterChain.doFilter(request, response);
    }
}

和测试类:

@RunWith(MockitoJUnitRunner.class)
public class SampleFilterTest {

    @Mock
    FilterConfig filterConfig;

    ServletRequest servletRequest;
    ServletResponse servletResponse;
    HttpServletRequest request;

    @Mock
    FilterChain filterChain;

    @Mock
    HttpServletResponse httpServletResponse;


    @InjectMocks
    SampleFilter sampleFilter;

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

    @Test
    public void init() throws ServletException {
        sampleFilter.init(filterConfig);
    }

    @Test
    public void doFilter() throws IOException, ServletException{
        //when(request.getHeader(Constants.USER_ID)).thenReturn("batman");
        sampleFilter.doFilter(servletRequest, servletResponse, filterChain);
    }

    @Test
    public void destroy() {
        sampleFilter.destroy();
    }
}

当我运行 doFilter() 时,它会在

处返回 NullPointerException
String userId= request.getHeader(Constants.USER_ID);

线。

如何避免这种情况?

我需要调用此方法并执行其中的任何内容以提供所需的代码覆盖率。

【问题讨论】:

    标签: servlets mockito junit4


    【解决方案1】:

    问题是

    HttpServletRequest request = (HttpServletRequest) servletRequest;
    

    正在转换为 null,因为您传入了一个不会转换为 HttpServletRequestServletRequest

    在被测方法中模拟您尝试将其转换为的实际类型。

    例如

    //...
    
    @Test
    public void doFilter() throws IOException, ServletException {
        //Arrange
        //mock HttpServletResponse so cast does not fail
        ServletRequest request = mock(HttpServletRequest.class);
        when(request.getHeader(Constants.USER_ID)).thenReturn("batman");
    
        ServletResponse response = mock(HttpServletResponse.class);
        //setup response as neded. Looks like `.getWriter().write(errorMsg);` needs mocking
    
        //Act
        sampleFilter.doFilter(request, response, filterChain);
    
        //Assert
        //...
    }
    

    【讨论】:

    • @Nikosi 非常感谢您指出这一点。方法似乎工作正常,但现在我有条件(if (StringUtils.isEmpty(userId)) & if(!isAuthorized))。你如何嘲笑他们?我可以在我的测试类中模拟它们,但是如何确保在调用实际测试时它被覆盖?
    • @Foxy 好吧,它不会进入StringUtils.isEmpty(userId) 条件,因为您已经设置了模拟以返回一个值。您需要确保isAuthorized 的计算结果为true,但没有足够的关于被测类的信息来建议如何修改该值。
    • 好吧,你究竟是如何为 if 条件设置模拟的?我可以为类和方法做,但不知道如何为条件做。
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多