编写JUnit测试用例请求调度程序时出错

时间:2014-03-12 15:58:12

标签: java junit mockito

在为Request调度程序编写测试用例时,我遇到了一些错误。 我的班级

@Override
        public void doFilter(ServletRequest request, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException
        {
            if(isMockAccountEnabled())
            {
                HttpServletRequest req = (HttpServletRequest)request;
                String reqUrl = req.getRequestURI();
                ApiUserDetails userDetails = userBean.getUserDetails();
                HttpSession session = req.getSession();
                if(isThisTestAccount(reqUrl, session))
                {
                    log.info(userDetails);
                    log.debug("Entering Test acount flow for the request "+reqUrl);
                    RequestDispatcher dispatcher = req.getRequestDispatcher("/mock/" + EnumService.returnMockService(reqUrl));
                    dispatcher.forward(request, resp);
                }
            }
        }

写的测试用例

@Mock
private FilterChain chain;


@InjectMocks
private MockAccountFilter mockAccountFilter = new MockAccountFilter();


MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpSession session = new MockHttpSession();
@Test
public void filterRequestMockFirst()
    throws Exception
{
    MockRequestDispatcher dispatcher =new MockRequestDispatcher("/mock/ABCTEST");
    when(request.getRequestDispatcher("/mock/ABCTEST")).thenReturn(dispatcher);
    request.setRequestURI("/check/employee/123456/false");
    mockAccountFilter.doFilter(request, response, chain);  
    Assert.assertTrue(request.getRequestURI().contains("/mock/ABCTEST"));

}

错误

when() requires an argument which has to be 'a method call on a mock'.

有人可以告诉我编写此测试用例的确切方法。

2 个答案:

答案 0 :(得分:4)

我没有足够的信息告诉您"编写此测试用例的确切方式",而StackOverflow并不是修复大块代码的好地方,但我可以告诉你为什么你得到那条消息。 :)

MockHttpServletRequest request = new MockHttpServletRequest();

有两种感觉" Mock"在这里:

  1. Mockito提供的模拟是基于接口自动生成的,并使用whenverify等静态方法进行操作。当且仅当您使用Mockito.mock@Mock时,才会使用MockitoJUnitRunner(或MockitoAnnotations.initMocks创建Mockito模拟。

  2. 名称以" Mock"开头的完整类,如MockHttpServletRequest,实际上是完整的类实现,碰巧变异或更改比实际收到的更容易通过J2EE。这些可能更准确地被称为" Fake",因为它们是用于测试的简单接口实现,不会验证行为并且不能通过Mockito工作。您可以确定他们不是Mockito模拟,因为您使用new MockHttpServletRequest();实例化它们。

  3. 例如,FilterChain可能会由Mockito提供。 MockHttpServletRequest request不是Mockito模拟,这就是您收到错误信息的原因。

    你最好的选择是选择一种类型的模拟或其他 - 或者可以工作 - 并确保你使用when声明(如果选择Mockito)或者设置者正确地准备这些模拟比如setRequestURI(如果你选择MockHttpSession式的模拟)。

答案 1 :(得分:2)

这看起来像是在使用Mockito进行单元测试。

正如消息告诉你做的那样“when(...)”你想要模拟/覆盖你的过程调用。 但是when过程期望你的请求对象是mockito框架的模拟对象。

即使您创建了一个模拟的ServletRequest对象,但这不是Mockito的模拟对象。

查看mockito开始页面;有一个例子:https://code.google.com/p/mockito/ 在第一个代码块/示例中查看第二行;有一个模拟对象创建如下:

List mockedList = mock(List.class);

意味着您需要像这样创建请求对象(而不是使用new-operator):

MockHttpServletRequest request = mock(MockHttpServletRequest.class);

希望这有助于解决您的问题。