在java中模拟https请求

假设我正在编写一个应用程序,我需要能够执行以下操作:

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

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

你基本上有两个选择:

1.摘要对框架的调用并对此进行测试。

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

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

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

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

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

希望这可以帮助。

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

 @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(); } 

如果您正在编写unit testing,则不需要任何外部依赖项。 来自api,

 GetMethod 

扩展

 HttpMethod 

所以你可以用你最喜欢的模拟库轻松模拟它。 您的

 method.getResponseBodyAsString() 

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

这是一个类似的问题

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

看看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!"); } } 

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

资源

  • thttpd: http ://www.acme.com/software/thttpd/

你有什么兴趣嘲笑这个“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(); } } 

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

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

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

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