如何在客户端模拟REST服务响应?

时间:2013-04-06 14:56:59

标签: rest junit mocking resteasy

我想在我的JUnit测试中使用预定义xml文件中的内容的响应主体来模拟RESTEasy客户端响应。请考虑遵循Person服务客户端API和Person实体:

package my.company.com;

import java.net.URI;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CookieStore;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;

public class PersonServiceClient {
    private final DefaultHttpClient httpClient;

public PersonServiceClient(String username, String password) {
    Credentials credentials = new UsernamePasswordCredentials(username, password);
    httpClient = new DefaultHttpClient();
    httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, credentials);
}

public Person[] getPersons() throws Exception
{
    URI url = new URI("http://www.mycompany.com/persons/");
    Person[] persons = getByRest(url, Person[].class);
    return persons;
}

private <T> T getByRest(URI url, Class<T> returnType) throws Exception {
    ClientRequest client = createClientRequest(url.toString());
    ClientResponse<T> response = client.get(returnType);
    return response.getEntity();
}

private ClientRequest createClientRequest(String url) {
    // Storing cookie to avoid creating new client for every call
    CookieStore cookieStore = new BasicCookieStore();
    HttpContext httpContext = new BasicHttpContext();
    httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
    ApacheHttpClient4Executor clientExecutor = new ApacheHttpClient4Executor(httpClient, httpContext);

    ClientRequest clientRequest = new ClientRequest(url, clientExecutor);
    return clientRequest;
}

@XmlRootElement(name = "resource")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
    private String type;
    private String name;
    private String addres;
    private String phone;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type= type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddres() {
        return addres;
    }

    public void setAddres(String addres) {
        this.addres = addres;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Person() {
    }
}
}

和response-test1.xml的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<collection>
    <resource>
        <type>Peson</type>
        <name>Christopher Monroe</name>
        <addres>Wall Street 2</addres>
        <phone>12345678</<phone>
    </resource>
    <resource>
        <type>Person</type>
        <name>John Dee</name>
        <addres>Down town 2</addres>
        <phone>2997562123</phone>
    </resource>
</collection>

如何使用上面的response-test.xml文件中的内容在下面的JUnit测试中模拟响应体?

@Test
public void testGetPersons() throws Exception{
    PersonServiceClient client = new PersonServiceClient("joe", "doe");
    Person[] persons = client.getPersons();
}

我试着在帖子Is there a client-side mock framework for RESTEasy?中关注示例,但它没有准确显示如何选择响应正文。

2 个答案:

答案 0 :(得分:1)

我建议使用WireMock来模拟服务器,而不是模仿RESTEasy客户端(免责声明 - 我写了它): http://wiremock.org/

它可以通过JUnit中的流畅Java API进行配置,并运行一个嵌入式Web服务器,该服务器提供存根响应并允许您验证从您的应用发送的请求。

我已经在这里写了一些关于不嘲笑HTTP客户端的理由: Introducing WireMock

答案 1 :(得分:0)

考虑使用工厂创建ClientRequest,然后模拟工厂以返回ClientRequest的模拟。