在java中模拟https请求

时间:2010-10-04 17:48:57

标签: java http mocking

假设我正在编写一个应用程序,我需要能够做到这样的事情:

String url = "https://someurl/";
GetMethod method = new GetMethod(URLEncoder.encode(url));
String content = method.getResponseBodyAsString();

有没有办法提供一个让我处理https请求的模拟服务器?我正在寻找的是一种编写单元测试的方法,但我需要能够模拟实际发送到https://someurl的部分,这样我才能得到已知的响应。

9 个答案:

答案 0 :(得分:4)

看看jadler(http://jadler.net),这是我一直在研究的http存根/模拟库。 1.0.0稳定版本刚刚发布,它应该提供您所要求的功能:

@Test
public void getAccount() {

    onRequest()
        .havingMethodEqualTo("GET")
        .havingURIEqualTo("/accounts/1")
        .havingBody(isEmptyOrNullString())
        .havingHeaderEqualTo("Accept", "application/json")
    .respond()
        .withTimeout(2, SECONDS)
        .withStatus(200)
        .withBody("{\"account\":{\"id\" : 1}}")
        .withEncoding(Charset.forName("UTF-8"))
        .withContentType("application/json; charset=UTF-8");

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port());
    final Account account = service.getAccount(1);

    assertThat(account, is(notNullValue()));
    assertThat(account.getId(), is(1));
}


@Test
public void deleteAccount() {

    onRequest()
        .havingMethodEqualTo("DELETE")
        .havingPathEqualTo("/accounts/1")
    .respond()
        .withStatus(204);

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port());
    service.deleteAccount(1);

    verifyThatRequest()
        .havingMethodEqualTo("DELETE")
        .havingPathEqualTo("/accounts/1")
    .receivedOnce();
}

答案 1 :(得分:3)

你基本上有两个选择:

<强> 1。摘要调用框架并测试它。

E.g。重构代码以允许您在某些时候注入模拟实现。有很多方法可以做到这一点。例如创建一个getUrlAsString()并模拟它。 (也在上面提出)。或者创建一个返回GetMethod对象的url getter工厂。然后工厂可以被嘲笑。

<强> 2。作为测试的一部分启动应用服务器,然后针对它运行您的方法。 (这将是更多的集成测试)

这可以通过多种方式实现。这可以在测试之外,例如maven jetty插件。或者测试可以以编程方式启动服务器。见:http://docs.codehaus.org/display/JETTY/Embedding+Jetty

通过https运行会使这变得复杂,但仍然可以使用自签名证书。但我会问自己 - 你究竟要测试什么?我怀疑你确实需要测试https功能,它是一种经过验证的技术。

我个人会选择选项1 - 您正在尝试测试外部库的功能。这通常是不必要的。将依赖项抽象到外部库也是一种很好的做法。

希望这有帮助。

答案 2 :(得分:2)

如果您正在编写单元测试,则不需要任何外部依赖项。来自api,

GetMethod 

延伸

HttpMethod

因此您可以使用自己喜欢的模拟库轻松模拟它。你的

method.getResponseBodyAsString()
可以模拟

调用以返回您想要的任何数据。

答案 3 :(得分:2)

Here's a similar question

它处理调试JSP页面,但它与静态页面的工作方式相同

答案 4 :(得分:1)

看看JWebUnit http://jwebunit.sourceforge.net/

这是一个测试的例子......它非常直观。

public class ExampleWebTestCase extends WebTestCase {
    public void setUp() {
        super.setUp();
        setBaseUrl("http://localhost:8080/test");
    }

    public void test1() {
        beginAt("/home");
        clickLink("login");
        assertTitleEquals("Login");
        setTextField("username", "test");
        setTextField("password", "test123");
        submit();
        assertTitleEquals("Welcome, test!");
    }
}

答案 5 :(得分:1)

您可以随时启动thttpd服务器作为单元测试的一部分,以便在本地提供请求。虽然理想情况下,你有一个经过良好测试的GetMethod,然后你可以模拟它,而不必为你的所有测试实际拥有一个远程服务器。

<强>资源

答案 6 :(得分:1)

您可以将该代码包装在某个类中并使用WebClient.getUrl()然后模拟(例如jmock)该方法返回存储的文件 - 比如说

expectation {
   oneOf("https://someurl/"), will(returnValue(someHTML));
}

答案 7 :(得分:1)

你有什么兴趣嘲笑这个“Get”调用,因为如果你正在寻找一个通用的Java模拟框架,它可以很好地与JUnit集成,并允许设置在合并到JUnit套件时自动声明的期望那么你真的应该看看jMock

现在没有更多的代码,很难确定这是否真的是你正在寻找的,但是一个(有点无用的)例子,类似于你编写的示例代码,将会是这样的:

class GetMethodTest {
@Rule public JUnitRuleMockery context = new JunitRuleMockery();

@Test
public void testGetMethod() throws Exception {
    // Setup mocked object with expectations
    final GetMethod method = context.mock(GetMethod.class);
    context.checking(new Expectations() {{
        oneOf (method).getResponseBodyAsString();
        will(returnValue("Response text goes here"));
    }});

    // Now do the checking against mocked object
    String content = method.getResponseBodyAsString();
}
}

答案 8 :(得分:0)

使用xml模拟存根服务器,它可以根据请求参数,标题等模拟静态http响应。配置和使用它非常简单。

http://xmlmimic.sourceforge.net/ http://sourceforge.net/projects/xmlmimic/