java java中的模拟https请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3857776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:43:11  来源:igfitidea点击:

mock https request in java

javahttpmocking

提问by dcp

Let's say I'm writing an application and I need to be able to do something like this:

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

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

Is there a way to provide a mock server that would let me handle the https request? What I'm looking for is a way to write unit tests, but I need to be able to mock the part that actually goes out to https://someurlso I can get a known response back.

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

采纳答案by Pablojim

You essentially have two options:

您基本上有两个选择:

1. Abstract the call to the framework and test this.

1. 抽象对框架的调用并对其进行测试。

E.g. refactor the code to allow you to inject a mock implementation at some point. There are many ways to do this. e.g. create a getUrlAsString() and mock that. (also suggested above). Or create a url getter factory that returns a GetMethod object. The factory then can be mocked.

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

2. Start up a app server as part of the test and then run your method against it. (This will be more of an integration test)

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

This can be achieved in an number of ways. This can be external to the test e.g. the maven jetty plugin. or the test can programmatically start up the server. see: http://docs.codehaus.org/display/JETTY/Embedding+Jetty

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

Running it over https will complicate this but it will still be possible with self signed certs. But I'd ask yourself - what exactly you want to test? I doubt you actually need to test https functionality, its a proven technology.

在 https 上运行它会使这变得复杂,但它仍然可以使用自签名证书。但我会问自己 - 你到底想测试什么?我怀疑您是否真的需要测试 https 功能,它是一项经过验证的技术。

Personally I'd go for option 1 - you are attempting to test functionality of an external library. That is usually unnecessary. Also it's good practice to abstract out your dependencies to external libraries.

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

Hope this helps.

希望这可以帮助。

回答by Jan Dudek

Take a look at jadler (http://jadler.net), an http stubbing/mocking library I've been working on for some time. The 1.0.0 stable version has been just released, it should provide the capabilities you requested:

看看 jadler ( http://jadler.net),我一直在研究一个 http stubbing/mocking 库。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();
}

回答by hvgotcodes

If you are writing a unit test, you dont want any external dependencies. from the api,

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

GetMethod 

extends

延伸

HttpMethod

so you can easily mock it with your favorite mocking library. Your

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

method.getResponseBodyAsString()

call can be mocked to return any data you want.

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

回答by micdah

To what extend are you interested in mocking this "Get" call, because if you are looking for a general purpose mocking framework for Java which integrates well with JUnit and allows to setup expectations which are automatically asserted when incorporated into a JUnit suite, then you really ought to take a look at jMock.

您对模拟这个“Get”调用有什么兴趣,因为如果您正在寻找一个通用的 Java 模拟框架,它与 JUnit 集成良好,并允许设置在合并到 JUnit 套件时自动断言的期望,那么您真的应该看看jMock

Now without more code, it's hard to determine whether this is actually what you are looking for, but a (somewhat useless) example, of something similar to the example code you wrote, would go something like this:

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

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

回答by Codemwnci

Take a look at JWebUnit http://jwebunit.sourceforge.net/

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

Here is an example of a test...Its really quite intuitive.

这是一个测试的例子......它真的很直观。

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

回答by zigdon

You could always launch a thttpdserver as part of your unit test to serve the requests locally. Though, ideally, you have a well tested GetMethod, and then you can just mock it, and not have to actually have a remote server around for ALL of your tests.

thttpd作为单元测试的一部分,您始终可以启动服务器以在本地为请求提供服务。不过,理想情况下,您有一个经过良好测试的GetMethod,然后您可以对其进行模拟,而实际上不必为您的所有测试配备远程服务器。

Resources

资源

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

回答by naumcho

You can wrap that code in some class and have WebClient.getUrl() and then mock (e.g. jmock) that method to return stored files - say

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

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

回答by user3406366

Use xml mimic stub server, that can simulate static http response based on request parameters, headers, etc. It is very simple to configure and use it.

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

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

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