如何对这个doFilter()方法进行单元测试?

huangapple go评论62阅读模式
英文:

How do I unit test this doFilter() method?

问题

以下是您要翻译的部分:

"Could someone help me with my unit test code? I always get Null Pointer Exception, because this piece of code in MyFilter returns null

Request jettyRequest = Request.getBaseRequest(servletRequest);

CODE

public class MyFilter implements Filter {

@Override
public void init(final FilterConfig filterConfig) {
LOG.info("My filter");
}

@Override
public void doFilter(
ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
final String startTime = String.valueOf(System.currentTimeMillis());

Request jettyRequest = Request.getBaseRequest(servletRequest);
String requestId = jettyRequest.getHeader(HttpHeaderUtils.APP_ID_HEADER);

filterChain.doFilter(servletRequest, httpResponse);

}

Unit Test

public class MyFilterTest {

private MockHttpServletRequest httpRequest;
private MyFilter myFilter = new MediaRequestFilter(8888);

@Before
public void init() {
httpRequest = new MockHttpServletRequest();
httpRequest.addHeader(HttpHeaderUtils.REQUEST_ID_HEADER, 1);

mediaRequestFilter.init(null);

}

@Test
public void doFilterTest() throws IOException, ServletException {
myFilter.doFilter(httpRequest, new MockHttpServletResponse(), new MockFilterChain());
Assert.assertTrue(Long.valueOf(httpRequest.getHeader(HttpHeaderUtils.REQUEST_ID_HEADER)) > 0);
}
}"

英文:

Could someone help me with my unit test code? I always get Null Pointer Exception, because this piece of code in MyFilter returns null

Request jettyRequest = Request.getBaseRequest(servletRequest);

CODE

 public class MyFilter implements Filter {


  @Override
  public void init(final FilterConfig filterConfig) {
    LOG.info("My filter");
  }

  @Override
  public void doFilter(
      ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
      throws IOException, ServletException {
    final String startTime = String.valueOf(System.currentTimeMillis());

    Request jettyRequest = Request.getBaseRequest(servletRequest);
    String requestId = jettyRequest.getHeader(HttpHeaderUtils.APP_ID_HEADER);

    filterChain.doFilter(servletRequest, httpResponse);
  }

Unit Test

public class MyFilterTest {

  private MockHttpServletRequest httpRequest;
  private MyFilter myFilter = new MediaRequestFilter(8888);

  @Before
  public void init() {
    httpRequest = new MockHttpServletRequest();
    httpRequest.addHeader(HttpHeaderUtils.REQUEST_ID_HEADER, 1);

    mediaRequestFilter.init(null);
  }

  @Test
  public void doFilterTest() throws IOException, ServletException {
    myFilter.doFilter(httpRequest, new MockHttpServletResponse(), new MockFilterChain());
    Assert.assertTrue(Long.valueOf(httpRequest.getHeader(HttpHeaderUtils.REQUEST_ID_HEADER)) > 0);
  }
}

答案1

得分: 1

我们可以使用间谍来帮助处理您的情况。您不能使用Mockito来模拟静态方法。您可以使用PowerMockito来做到这一点,但我将向您展示一种不同的方法。

所以,我稍微修改了您的类。假设它仍然是您的代码。我只是添加了一个Request类,因为我不想真的搜索那个特定的类。

@Slf4j
public class MyFilter implements Filter {

    @Override
    public void init(final FilterConfig filterConfig) {
        log.info("My filter");
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        Request jettyRequest = getBaseRequest(servletRequest);
        String requestId = jettyRequest.getHeader("Some header");

        log.info("Request id : {}", requestId);

        filterChain.doFilter(servletRequest, servletResponse);
    }

    Request getBaseRequest(ServletRequest servletRequest) {
        return Request.getBaseRequest(servletRequest);
    }

}

请注意,我将静态方法调用转换为实例方法调用,并将该方法设为包私有。我这样做是为了能够在我们的测试中访问它。

这是测试:

@ExtendWith(MockitoExtension.class)
class MyFilterTest {

    @Test
    @SneakyThrows
    void testDoFilter() {
        final MyFilter myFilter = spy(new MyFilter());

        final ServletRequest req = mock(ServletRequest.class);
        final ServletResponse res = mock(ServletResponse.class);
        final FilterChain chain = mock(FilterChain.class);

        doReturn(new Request()).when(myFilter).getBaseRequest(req);

        myFilter.doFilter(req, res, chain);

        verify(chain).doFilter(req, res);
        verify(myFilter).getBaseRequest(req);
    }

}

我使用间谍来模拟对象的特定部分,即静态方法调用。就是这样。您可以模拟Request对象并进行各种验证。

英文:

We can use spies to help with your case. You cannot mock the static method with Mockito. You can use PowerMockito to do it, but I will show you a different way.

So, I changed your class a little bit. Just assume it is still your code. I just added a Request class because I did not want to search for that particular class really.

@Slf4j
public class MyFilter implements Filter {

    @Override
    public void init(final FilterConfig filterConfig) {
        log.info("My filter");
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        Request jettyRequest = getBaseRequest(servletRequest);
        String requestId = jettyRequest.getHeader("Some header");

        log.info("Request id : {}", requestId);

        filterChain.doFilter(servletRequest, servletResponse);
    }

    Request getBaseRequest(ServletRequest servletRequest) {
        return Request.getBaseRequest(servletRequest);
    }

}

Pay attention that I converted that static method call to an instance method call and made that method package-private. I did that to be able to access it in our tests.

Here's the test

@ExtendWith(MockitoExtension.class)
class MyFilterTest {

    @Test
    @SneakyThrows
    void testDoFilter() {
        final MyFilter myFilter = spy(new MyFilter());

        final ServletRequest req = mock(ServletRequest.class);
        final ServletResponse res = mock(ServletResponse.class);
        final FilterChain chain = mock(FilterChain.class);

        doReturn(new Request()).when(myFilter).getBaseRequest(req);

        myFilter.doFilter(req, res, chain);

        verify(chain).doFilter(req, res);
        verify(myFilter).getBaseRequest(req);
    }

}

I am using a spy to mock a specific part of the object which is that static method call. That's it. You can mock Request object and do whole sorts of verifications on it.

huangapple
  • 本文由 发表于 2020年7月22日 13:27:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63027486.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定