Java 测试JAX-RSWeb服务?
我目前正在寻找为基于(RESTfulWeb服务的JavaAPI)的Web服务创建自动化测试的方法 我基本上需要一种方法来向它发送某些输入,并验证我是否得到了预期的响应。我更愿意通过JUnit实现这一点,但我不确定如何实现这一点 您使用什么方法来测试web服务Java 测试JAX-RSWeb服务?,java,web-services,unit-testing,junit,jax-rs,Java,Web Services,Unit Testing,Junit,Jax Rs,我目前正在寻找为基于(RESTfulWeb服务的JavaAPI)的Web服务创建自动化测试的方法 我基本上需要一种方法来向它发送某些输入,并验证我是否得到了预期的响应。我更愿意通过JUnit实现这一点,但我不确定如何实现这一点 您使用什么方法来测试web服务 更新:正如entzik指出的那样,将web服务与业务逻辑分离允许我对业务逻辑进行单元测试。但是,我还想测试正确的HTTP状态码等。您可能编写了一些实现业务逻辑的java代码,然后为其生成了web服务端点 一件重要的事情是独立测试您的业务逻辑
更新:正如entzik指出的那样,将web服务与业务逻辑分离允许我对业务逻辑进行单元测试。但是,我还想测试正确的HTTP状态码等。您可能编写了一些实现业务逻辑的java代码,然后为其生成了web服务端点 一件重要的事情是独立测试您的业务逻辑。因为它是纯java代码,所以可以通过常规的JUnit测试来实现 现在,由于web服务部分只是一个端点,您需要确保生成的管道(存根等)与java代码同步。您可以通过编写JUnit测试来调用生成的web服务java客户端来实现这一点。当您在不更新web服务内容的情况下更改java签名时,这将让您知道
如果web服务管道是在每次生成时由生成系统自动生成的,那么可能不需要测试端点(假设所有端点都正确生成)。取决于您的偏执程度。我使用Apache调用Restful服务。HTTP客户端库允许您轻松执行get、post或任何其他需要的操作。如果您的服务使用JAXB进行xml绑定,您可以创建一个JAXBContext来序列化和反序列化来自HTTP请求的输入和输出。附带了一个非常好的RESTful客户端API,使编写单元测试变得非常容易。请参阅Jersey附带的示例中的单元测试。我们使用此方法测试中的REST支持,如果您对感兴趣,尽管从发布问题之日起已经太晚了,但我们认为这可能对其他有类似问题的人有用。 Jersey附带了一个名为的测试框架,允许您测试RESTful Web服务,包括响应状态代码。您可以使用它在Grizzly、HTTPServer和/或EmbeddedGlassFish等轻量级容器上运行测试。此外,该框架还可用于在常规web容器(如GlassFish或Tomcat)上运行测试 一件重要的事情是独立测试您的业务逻辑 我当然不会假设编写JAX-RS代码并希望对接口进行单元测试的人不知何故,出于某种奇怪、无法解释的原因,忘记了他或她可以对程序的其他部分进行单元测试的概念,包括业务逻辑类。陈述显而易见的事实几乎没有什么帮助,人们反复强调,这些反应也需要测试 Jersey和RESTEasy都有客户端应用程序,在RESTEasy的情况下,您可以使用相同的注释(甚至可以去掉注释接口,并在测试的客户端和服务器端使用)
不要指望这项服务能为你做什么;休息一下你能为这项服务做些什么 您可以尝试使用Java(使用JUnit或TestNG)测试REST服务和验证响应,这非常简单。正如James所说;泽西岛有内置的。一个简单的hello world示例如下: 用于maven集成的pom.xml。运行
mvn测试时
。框架启动一个灰色容器。您可以通过更改依赖项来使用jetty或tomcat
...
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.16</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>2.16</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.16</version>
<scope>test</scope>
</dependency>
</dependencies>
...
HelloWorld.java
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/")
public final class HelloWorld {
@GET
@Path("/hello")
@Produces(MediaType.TEXT_PLAIN)
public String sayHelloWorld() {
return "Hello World!";
}
}
HelloWorldTest.java
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.core.Application;
import static org.junit.Assert.assertEquals;
public class HelloWorldTest extends JerseyTest {
@Test
public void testSayHello() {
final String hello = target("hello").request().get(String.class);
assertEquals("Hello World!", hello);
}
@Override
protected Application configure() {
return new ResourceConfig(HelloWorld.class);
}
}
您可以查看示例应用程序。请查看。这可以在幕后使用jersey客户端为JAX-RSWebService类生成代理实现。实际上,您可以从单元测试中将webservice方法称为简单的java方法。处理http身份验证
如果您需要简单地运行测试,那么就不需要生成代码,这样做很方便
Dislclaimer:我是这个库的作者。据我所知,这个问题的作者的主要目的是将JAX RS层与业务层解耦。而单元测试只是第一个。我们必须解决两个基本问题:
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import com.brandmaker.skinning.service.SomeBean;
/**
* Created by alexandr on 31.07.15.
*/
@Path("/entities")
public class RestBean
{
@Inject
SomeBean bean;
@GET
public String getEntiry()
{
return bean.methodToBeMoked();
}
}
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.google.common.collect.Sets;
/**
*/
@ApplicationPath("res")
public class JAXRSConfiguration extends Application
{
@Override
public Set<Class<?>> getClasses()
{
return Sets.newHashSet(RestBean.class);
}
}
public class SomeBean
{
public String methodToBeMoked()
{
return "Original";
}
}
import javax.enterprise.inject.Specializes;
import com.brandmaker.skinning.service.SomeBean;
/**
*/
@Specializes
public class SomeBeanMock extends SomeBean
{
@Override
public String methodToBeMoked()
{
return "Mocked";
}
}
@RunWith(Arquillian.class)
public class RestBeanTest
{
@Deployment
public static WebArchive createDeployment() {
WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
.addClasses(JAXRSConfiguration.class, RestBean.class, SomeBean.class, SomeBeanMock.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
System.out.println(war.toString(true));
return war;
}
@Test
public void should_create_greeting() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://127.0.0.1:8181/test/res/entities");
//Building the request i.e a GET request to the RESTful Webservice defined
//by the URI in the WebTarget instance.
Invocation invocation = target.request().buildGet();
//Invoking the request to the RESTful API and capturing the Response.
Response response = invocation.invoke();
//As we know that this RESTful Webserivce returns the XML data which can be unmarshalled
//into the instance of Books by using JAXB.
Assert.assertEquals("Mocked", response.readEntity(String.class));
}
}
import javax.inject.inject;
导入javax.ws.rs.GET;
导入javax.ws.rs.Path;
导入com.brandmaker.skining.service.SomeBean;
/**
*由alexandr于2015年7月31日创建。
*/
@路径(“/实体”)
公共类RestBean
{
@注入
豆豆;
@得到
公共字符串getEntry()
{
return bean.methodToBemoke();
}
}
导入java.util.Set;
导入javax.ws.rs.ApplicationPath;
导入javax.ws.rs.core.Application;
导入com.google.common.collect.set;
/**
*/
@应用程序路径(“res”)
公共类JAXRSConfiguration扩展了应用程序
{
@凌驾
公共设置保持简单。看看哪些可以从Maven Central导入
<dependency>
<groupId>org.valid4j</groupId>
<artifactId>http-matchers</artifactId>
<version>1.0</version>
</dependency>
你说得很对,虽然我还需要测试返回的实际HTTP响应,特别是HTTP状态码。re:现在坏链接你可以找到jersey/samples中提到的示例,这些示例显示单元测试,基本上是通过jersey的消费者使用web资源。这个项目在GitHub上,在src/te中查找测试st folder:我不怀疑这个答案,但我觉得非常有趣的是,Jersey总是进入JAX-RS对话,而在某些情况下(不幸的是,确切地说是WebSphere)它不可用并重新启动
<dependency>
<groupId>org.valid4j</groupId>
<artifactId>http-matchers</artifactId>
<version>1.0</version>
</dependency>
// Statically import the library entry point:
import static org.valid4j.matchers.http.HttpResponseMatchers.*;
// Invoke your web service using plain JAX-RS. E.g:
Client client = ClientBuilder.newClient();
Response response = client.target("http://example.org/hello").request("text/plain").get();
// Verify the response
assertThat(response, hasStatus(Status.OK));
assertThat(response, hasHeader("Content-Encoding", equalTo("gzip")));
assertThat(response, hasEntity(equalTo("content")));
// etc...