英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论