如何使用 Junit 在 servlet 中测试业务逻辑?

How do I test business logic in a servlet using Junit?

我有一个 servlet,它在调用 DAO 方法之前执行一些先决条件检查,如下所示:

private void processRequest(HttpServletRequest request, HttpServletResponse response){
        if(a condition is met)
            myDAOFunction();
        else
            redirect();
}

我应该如何构建我的单元测试来验证是否对于某个请求,servlet 调用我的函数,对于不满足条件的其他请求,它会重定向页面?

我已经尝试过这个解决方案:因为如果我的 DAO function 被调用,它会在数据库中进行一些更改,并且通过它我可以测试 servlet 是否正确处理请求和响应。但我认为这不是一个很好的解决方案。

那么你需要验证servlet是否可以正确地与DAO相关代码进行交互。如果您的设计已经将与 DB 交互相关的所有代码分离并封装在 DAO 服务 class 中,您可以通过使用 Mockito 模拟此 DAO 服务 class 轻松测试它,然后验证预期的方法是否在使用预期参数调用模拟 DAO 服务。如果不是,请重构您的代码,使其具有此单独的 DAO 服务 class.

为了模拟 MockHttpServletRequestMockHttpServletResponsespring-test 已经提供了一些实用程序来创建它们,这对于测试 Servlet 东西很有用。虽然它们主要设计用于与 spring-mvc 编写的代码一起使用,但它也应该用于非 spring 编写的代码,并且与 Mockito 相比应该更方便使用。

假设您的 servlet 名为 FooBarServlet,测试用例可能如下所示:

@ExtendWith(MockitoExtension.class)
public class FooBarServletTest { 

        @Mock
        DaoService daoService;

        @Test
        void testSaveToDatabase(){
                    
            FooBarServlet sut = new FooBarServlet(daoService);

            MockHttpServletRequest request = MockMvcRequestBuilders.get("/foobar")
                ......   
                .buildRequest(new MockServletContext());
            MockHttpServletResponse response = new MockHttpServletResponse();

            sut.processRequest(request, response);
            verify(daoService).save("xxxxxx");

        }

        @Test
        void testRedirect(){
                    
            FooBarServlet sut = new FooBarServlet(daoService);

            MockHttpServletRequest request = MockMvcRequestBuilders.get("/foobar")
                ......   
                .buildRequest(new MockServletContext());
            MockHttpServletResponse response = new MockHttpServletResponse();

            sut.processRequest(request, response);
            verify(daoService,never()).save(any());
        }

}