gpt4 book ai didi

spring - 在使用 Spring 进行集成测试期间模拟外部服务器

转载 作者:IT老高 更新时间:2023-10-28 13:57:48 26 4
gpt4 key购买 nike

我有一个 Spring Web 服务器,它根据请求对某些第三方 Web API 进行外部调用(例如,检索 Facebook oauth token )。从这个调用中获取数据后,它会计算一个响应:

@RestController
public class HelloController {
@RequestMapping("/hello_to_facebook")
public String hello_to_facebook() {
// Ask facebook about something
HttpGet httpget = new HttpGet(buildURI("https", "graph.facebook.com", "/oauth/access_token"));
String response = httpClient.execute(httpget).getEntity().toString();
// .. Do something with a response
return response;
}
}

我正在编写一个集成测试,检查在我的服务器上点击 url 会导致一些预期的结果。但是我想在本地模拟外部服务器,这样我什至不需要互联网访问来测试这一切。最好的方法是什么?

我是 Spring 的新手,这就是我目前所拥有的。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({})
public class TestHelloControllerIT {
@Test
public void getHelloToFacebook() throws Exception {
String url = new URL("http://localhost:8080/hello_to_facebook").toString();
//Somehow setup facebook server mock ...
//FaceBookServerMock facebookMock = ...

RestTemplate template = new TestRestTemplate();
ResponseEntity<String> response = template.getForEntity(url, String.class);
assertThat(response.getBody(), equalTo("..."));

//Assert that facebook mock got called
//facebookMock.verify();
}
}

实际的设置更复杂 - 我正在制作 Facebook oauth 登录,所有这些逻辑都不在 Controller 中,而是在各种 Spring Security 对象中。但是我怀疑测试代码应该是相同的,因为我只是点击 url 并期待响应,不是吗?

最佳答案

在尝试了各种场景之后,这是一种如何在对主代码干预最少的情况下实现所要求的内容的一种方法

  1. 重构您的 Controller 以使用第三方服务器地址的参数:

    @RestController
    public class HelloController {
    @Value("${api_host}")
    private String apiHost;

    @RequestMapping("/hello_to_facebook")
    public String hello_to_facebook() {
    // Ask facebook about something
    HttpGet httpget = new HttpGet(buildURI("http", this.apiHost, "/oauth/access_token"));
    String response = httpClient.execute(httpget).getEntity().toString();
    // .. Do something with a response
    return response + "_PROCESSED";
    }
    }

'api_host' 等于 src/main/resources 中 application.properties 中的 'graph.facebook.com'

  1. 在 src/test/java 文件夹中创建一个模拟第三方服务器的新 Controller 。

  2. 覆盖 'api_host' 以测试到 'localhost'。

为简洁起见,以下是第 2 步和第 3 步的代码:

@RestController
class FacebookMockController {
@RequestMapping("/oauth/access_token")
public String oauthToken() {
return "TEST_TOKEN";
}
}

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest({"api_host=localhost",})
public class TestHelloControllerIT {
@Test
public void getHelloToFacebook() throws Exception {
String url = new URL("http://localhost:8080/hello_to_facebook").toString();
RestTemplate template = new TestRestTemplate();
ResponseEntity<String> response = template.getForEntity(url, String.class);
assertThat(response.getBody(), equalTo("TEST_TOKEN_PROCESSED"));

// Assert that facebook mock got called:
// for example add flag to mock, get the mock bean, check the flag
}
}

有没有更好的方法来做到这一点?感谢所有反馈!

附:以下是将这个答案放入更现实的应用程序时遇到的一些复杂情况:

  1. Eclipse 将测试和主配置混合到类路径中,因此您可能会通过测试类和参数搞砸主配置:https://issuetracker.springsource.com/browse/STS-3882使用 gradle bootRun 来避免它

  2. 如果你设置了 spring 安全,你必须在安全配置中打开对你的模拟链接的访问。要附加到安全配置而不是弄乱主配置配置:

    @Configuration
    @Order(1)
    class TestWebSecurityConfig extends WebSecurityConfig {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http
    .authorizeRequests()
    .antMatchers("/oauth/access_token").permitAll();
    super.configure(http);
    }
    }
  3. 在集成测试中点击 https 链接并不简单。我最终使用带有自定义请求工厂和配置 SSLConnectionSocketFactory 的 TestRestTemplate。

关于spring - 在使用 Spring 进行集成测试期间模拟外部服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29550098/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com