【问题标题】:How to test a restful web service in java如何在java中测试一个宁静的Web服务
【发布时间】:2016-06-17 10:36:30
【问题描述】:

我在工作中编写了一个 Web 服务,现在我想编写一些测试。我对如何测试它们持怀疑态度,但我知道我需要哪些工具:JUnit 4,也许还有一个嵌入式应用程序容器,例如 Tomcat,以及 Jersey Client。不过,这是我的方法:

  1. 创建一个启动嵌入式应用程序容器 (Tomcat) 的测试类。然后,将 Web 服务部署到它并使用 Jersey 客户端进行测试调用。这是我到目前为止所做的方式。问题来了:要部署 Web 服务,我必须先创建 WAR。这是一个问题,因为在使用 Maven 构建应用程序时,首先执行测试,然后构建 WAR;我认为这实际上是一个循环。是否可以在不需要战争的情况下部署我的 web 应用程序?这是我的测试课:

    public class TestAutenticacionService {
    
        private final String mWorkingDir = "C://Users//Asasa//workspace//myWebApp//";
        private Tomcat tomcat = null;
        private WebTarget webTarget = null;
        private ObjectMapper mapper = new ObjectMapper();
        private Long idClienteCorrecto = 787538L;   
    
        @Before
        public void setUp() throws Exception {  
            tomcat = new Tomcat();
            tomcat.setPort(9090);
            tomcat.setBaseDir(mWorkingDir);
            tomcat.getHost().setAppBase(mWorkingDir);
            tomcat.getHost().setAutoDeploy(true);
            tomcat.getHost().setDeployOnStartup(true);
            tomcat.getServer().addLifecycleListener(new VersionLoggerListener());
            tomcat.getHost().addLifecycleListener(new HostConfig());
    
            try {
                tomcat.addWebapp("/bidegiWsCli", "C:/Users/Asasa/workspace/myWebApp/myWebApp.war");
                tomcat.start();
                System.out.println("Tomcat iniciado en " + tomcat.getHost());
    
                webTarget = buildClientWs();
    
            } catch (LifecycleException e) {
                System.err.println("Tomcat no se pudo iniciar.");
                e.printStackTrace();
            }
        }
    
        @After
        public void tearDown() throws Exception {
            if(tomcat != null){
                try {
                    tomcat.stop();
                    System.out.println("Tomcat parado.");
                } catch (LifecycleException e) {
                    System.err.println("Error al intentar parar Tomcat.");
                    e.printStackTrace();
                }   
            }
        }
    
        @Test
        public void test() {
    
            WebTarget loginTgt = webTarget.path("login");
    
            // Probamos un login correcto:
            WebTarget loginTgtOk = loginTgt.queryParam("Aus", "764577676t").queryParam("Pass", "****");
            Response respOk = loginTgtOk.request(MediaType.APPLICATION_JSON).get();
            String strLrOk = (String) respOk.readEntity(String.class);
            try {
                LoginResponse lrOk = mapper.readValue(strLrOk, LoginResponse.class);
                Long idClienteOk = lrOk.getIdCliente();
                assertEquals(idClienteOk, idClienteCorrecto);
            } catch (Exception e) {
                try {
                    mapper.readValue(strLrOk, ExceptionResponse.class);
                    assertTrue(true);
                } catch (JsonParseException e1) {
                    System.err.println("Error JsonParseException: " + e1.getMessage());
                    e1.printStackTrace();
                } catch (JsonMappingException e1) {
                    System.err.println("Error JsonMappingException: " + e1.getMessage());
                    e1.printStackTrace();
                } catch (IOException e1) {
                    System.err.println("Error IOException: " + e1.getMessage());    
                    e1.printStackTrace();
                }
            }
    
            // Probamos un login incorrecto:
            WebTarget loginTgtWrong = loginTgt.queryParam("Aus", "764577676t").queryParam("Password", "***");
            Response respWrong = loginTgtWrong.request(MediaType.APPLICATION_JSON).get();
            String strLrWrong = (String) respWrong.readEntity(String.class);
            try {
                LoginResponse lrWrong = mapper.readValue(strLrWrong, LoginResponse.class);
                Long idClienteWrong = lrWrong.getIdCliente();
                assertNotEquals(idClienteWrong, idClienteCorrecto);
            } catch (Exception e) {
                try {
                    mapper.readValue(strLrWrong, ExceptionResponse.class);
                    assertTrue(true);
                } catch (JsonParseException e1) {
                    System.err.println("Error JsonParseException: " + e1.getMessage());
                    e1.printStackTrace();
                } catch (JsonMappingException e1) {
                    System.err.println("Error JsonMappingException: " + e1.getMessage());
                    e1.printStackTrace();
                } catch (IOException e1) {
                    System.err.println("Error IOException: " + e1.getMessage());
                    e1.printStackTrace();
                }
            }
    
        }
    
        private WebTarget buildClientWs(){
            Client client = ClientBuilder.newClient();
            return client.target("http://localhost:9090").path("myWebApp").path("resources").path("Auth");
        }
    
    }
    
  2. 另一种方法是直接执行 Web 服务方法,无需应用程序容器。我不确定这一点,因为我不会测试 Web 服务本身。

对此有什么想法吗?

提前谢谢你

【问题讨论】:

标签: java web-services testing junit jersey


【解决方案1】:

如果您使用的是 Jersey,那么您可以使用内置的测试框架。

https://jersey.java.net/documentation/latest/test-framework.html

【讨论】:

  • 谢谢!这就是我想要的:)
【解决方案2】:

如果您尝试编写单元测试,那么只需创建模拟对象并仅测试您的方法。

但如果您的需求是对整个 web 服务进行测试,那么您可以进行集成测试或使用 Postman 插件。

【讨论】:

  • 感谢您的回复。我正在寻找的是测试 web 服务,所以最好的方法是使用 jersey 内置的测试框架。
【解决方案3】:

有多个选项不是互斥的:

  • 组件测试。可以在没有 HTTP 流量的情况下编写测试。通过直接调用服务方法或使用 Jersey 的内存提供程序(其他框架通常具有自己的功能,例如 MockMVC 附带的 Spring MVC):

    org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-inmemory

  • 系统测试。这将需要调用实际的 HTTP 请求。 Java 世界中事实上的标准库是RestAssured - 它很好并且与框架无关(尽管也对 Spring MVC 有一些特殊的支持)。您必须以某种方式运行应用程序 - 通过启动内存中的 Jetty/Tomcat 或通过使用外部脚本单独部署应用程序。你也可以试试Arquillian,它是专门为部署测试应用而创建的(虽然没试过)。

使用单元和组件测试检查大部分逻辑通常是个好主意,将一些粗粒度检查留给系统测试。你don't want 进行许多系统测试,因为它们运行起来会慢得多,也更难维护。

【讨论】:

    【解决方案4】:

    我认为您使用嵌入式 Web 服务器来运行该服务是正确的。诚然,您还没有验证打包到 WAR/docker-image/whatever 中是否正确,但是必须在级别上进行测试,并且在 Web 服务 API 级别上进行功能测试会为您提供有价值的反馈,并且可以快速周转。

    对于工具,我建议保持简单。 使用 JUnit + http-matchers (https://github.com/valid4j/http-matchers)

    【讨论】:

      猜你喜欢
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 2013-07-21
      • 2012-01-08
      • 2018-04-21
      • 2012-10-23
      • 1970-01-01
      相关资源
      最近更新 更多