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

Posted

技术标签:

【中文标题】如何使用 Junit 在 servlet 中测试业务逻辑?【英文标题】:How do I test business logic in a servlet using Junit? 【发布时间】:2022-01-21 10:00:48 【问题描述】:

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

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

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

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

【问题讨论】:

【参考方案1】:

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

对于模拟 MockHttpServletRequestMockHttpServletResponse ,spring-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());
        


【讨论】:

我明白了,谢谢。假设那里的verify.save() 方法可以帮我验证daoService 是否确实对数据库进行了一些更改,而不是手动创建一个sql 字符串来查询相应的表以检查更改? 如果是这样,它会在测试后自动回滚保存还是我必须手动这样做?我对 Mockito 有点陌生 Mockito创建的mocked只是内存中的一个java对象。它不会真正与您的数据库交互以将内容保存到其中。所以数据是否回滚与事物无关。

以上是关于如何使用 Junit 在 servlet 中测试业务逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

在 Servlet 和 JDBC 中为 JUnit 分离 H2 数据库 [关闭]

JUNIT测试

maven多模块下使用JUnit进行单元测试

如何将JUnit 4测试添加到JUnit 3测试套件中

如何在Gradle中使用JUnit 5?

如何使用eclipse进行junit测试