我正在尋找方法爲JAX-RS(基於REST風格的Web服務的Java API)基於Web服務創建自動化測試。單元測試JAX-RS Web服務?
我基本上需要一種方式來發送它的某些輸入,並驗證我得到了預期的響應。我寧願通過JUnit來做到這一點,但我不確定如何實現。
你用什麼方法來測試你的web服務?
更新:正如entzik指出的那樣,將Web服務從業務邏輯中分離出來,使我能夠對業務邏輯進行單元測試。但是,我也想測試正確的HTTP狀態代碼等。
我正在尋找方法爲JAX-RS(基於REST風格的Web服務的Java API)基於Web服務創建自動化測試。單元測試JAX-RS Web服務?
我基本上需要一種方式來發送它的某些輸入,並驗證我得到了預期的響應。我寧願通過JUnit來做到這一點,但我不確定如何實現。
你用什麼方法來測試你的web服務?
更新:正如entzik指出的那樣,將Web服務從業務邏輯中分離出來,使我能夠對業務邏輯進行單元測試。但是,我也想測試正確的HTTP狀態代碼等。
Jersey附帶一個很好的RESTful客戶端API,使得編寫單元測試非常簡單。請參閱Jersey附帶的示例中的單元測試。我們使用這種方法在Apache Camel測試REST支持,如果你有興趣的test cases are here
回覆:現在不好鏈接 你可以在澤西/樣本中找到顯示單元測試的例子,基本上是使用澤西的消費者來消費網絡資源。 http://download.java.net/maven/2/com/sun/jersey/samples/bookstore/1.1.5-ea-SNAPSHOT – rogerdpack 2009-11-09 19:55:42
再次連接不良 - 請介意更新? – 2015-07-10 19:19:28
這個項目在GitHub上,在src/test文件夾中找到測試:https://github.com/jersey/jersey/tree/master/examples/bookstore-webapp – Venkat 2016-03-24 15:01:53
您可能寫了一些實現您的業務邏輯的java代碼,然後爲其生成了Web服務端點。
要做的重要事情是獨立測試您的業務邏輯。由於它是純Java代碼,因此您可以使用常規的JUnit測試來完成此操作。
現在,由於Web服務部分只是一個終點,您要確保生成的管道(存根等)與您的java代碼同步。你可以通過編寫調用生成的Web服務Java客戶端的JUnit測試來實現這一點。這會讓你知道什麼時候改變你的java簽名而不更新web服務的東西。
如果您的Web服務管道是由您的構建系統在每個構建中自動生成的,則可能不需要測試端點(假設它已全部正確生成)。取決於你的偏執狂水平。
雖然我也需要測試返回的實際HTTP響應,特別是HTTP狀態代碼,但您說得很對。 – Einar 2008-09-25 10:58:14
我使用Apache的HTTPClient (http://hc.apache.org/)來調用Restful Services。 HTTP客戶端庫允許您輕鬆執行獲取,發佈或其他任何您需要的操作。如果您的服務使用JAXB進行xml綁定,則可以創建一個JAXBContext來對來自HTTP請求的輸入和輸出進行序列化和反序列化。
雖然它可以發佈問題的日期太晚了,認爲這可能是其他人誰也有類似的問題非常有用。 Jersey帶有一個名爲Jersey Test Framework的測試框架,它允許您測試RESTful Web服務,包括響應狀態代碼。您可以使用它來在像Grizzly,HTTPServer和/或EmbeddedGlassFish這樣的輕量級容器上運行測試。此外,該框架可用於在GlassFish或Tomcat等常規Web容器上運行測試。
一個重要的事情要做的,就是獨立測試你的業務邏輯
我當然不會認爲誰寫的JAX-RS碼和人正在尋求單元測試接口在某種程度上是出於某種奇怪的,不可理解的原因,忘記了他或她可以單元測試程序的其他部分(包括業務邏輯類)的概念。陳述這些顯而易見的事情並沒有什麼幫助,而且反覆提出的觀點也需要進行測試。
Jersey和RESTEasy都有客戶端應用程序,在RESTEasy的情況下,您可以使用相同的註釋(即使是帶註釋的接口並在您的測試的客戶端和服務器端使用)。
REST不是這個服務可以爲你做什麼; REST你可以爲這項服務做些什麼。
您可以試用REST Assured,這使得它很容易很簡單測試REST服務和驗證Java中的響應(使用JUnit或TestNG)。正如詹姆斯所說的那樣:
澤西島內置test framework。一個簡單的Hello World例子可以是這樣的:
pom.xml用於maven集成。當你運行mvn test
。框架開始一個灰熊的容器。您可以通過更改依賴關係來使用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>
...
ExampleApp.java
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class ExampleApp extends Application {
}
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);
}
}
您可以檢查this示例應用程序。
看看Alchemy rest client generator。這可以在場景後面使用平臺客戶端爲您的JAX-RS webservice類生成代理實現。實際上,您將從單元測試中將您的webservice方法作爲簡單的java方法調用。還處理http身份驗證。
如果您需要簡單地運行測試以便於使用,則不涉及代碼生成。
免責聲明:我是該圖書館的作者。
據我所知,這個問題的作者的主要目的是分離JAX RS層與商業之一。而單元測試只有第一個。兩個基本問題下面我們就來解決:在測試
第一個問題是用Arquillian解決的。 在arquillican and mock
第二個是完全說明這裏是代碼的一個例子,它可能會有所不同,如果你使用其他應用服務器,但我希望你會得到的基本理念和優勢。
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));
}
}
有兩點要注意:
希望它能幫上忙。
保持簡單。看看可以從Maven Central導入的https://github.com/valid4j/http-matchers。
<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...
好問題 - 但是我會說,如果你是通過HTTP測試,然後這讓我感到這是集成測試。 – 2011-05-03 14:46:03
湯姆。你是絕對正確的。我們應該爲此注入一個虛擬HTTP模擬器/輕量級容器。在node.js世界supertest使這個。你可以模擬express.js。 – 2015-02-25 18:38:12