java - 模拟子服务的 REST 请求

标签 java spring spring-boot integration-testing

我尝试使用 MockMvc 在集成测试套件中测试 @RestController

@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class WebControllerIT {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void getStatusReurnsSomething() throws Exception {
        this.mockMvc.perform(get("/status")).andExpect(status().isOk());
    }
}

@RestController (WebController) 调用注入(inject)的 @Service (RestClientService),它使用 RestTemplate 调用另一个 REST 服务器。这会导致运行测试时出现以下错误。

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://test123.com/42/status": test123.com; nested exception is java.net.UnknownHostException: test123.com

我使用 MockRestServiceServer 进行 @Service 本身的集成测试,但不知道如何在 @RestController 的测试中实现这一点.

如何模拟 RestTemplate 的正确 REST 调用?

<小时/>

@RestController 类。

@RestController
public class WebController {
    private final RestClientService service;

    @Autowired
    public WebController(RestClientService service) {this.service = service;}

    @GetMapping("/status")
    public String getStatus() {
        // extract pid from database ...
        int pid = 42;

        return this.service.getStatus(42);
    }
}

@Service类。

@Service
public class RestClientService {
    private final RestTemplate restTemplate;

    public RestClientService(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

    public String getStatus(int pid) {
        String url = String.format("http://test123.com/%d/status", pid);
        return this.restTemplate.getForObject(url, String.class);
    }
}

最佳答案

集成/单元测试不是这样工作的。这种测试的目的是运行您的代码并确保满足所有业务需求,但不会影响其他系统或数据库。在您的情况下,您应该这样做不要访问 test123.com 来取回数据。这里需要做的是您应该模拟该方法。

public String getStatus(int pid) {
    String url = String.format("http://test123.com/%d/status", pid);
    return this.restTemplate.getForObject(url, String.class);
}

这样控件就不会进入这个方法,而是返回模拟数据(Dummy data)。

例如,假设此方法返回两种状态,您需要根据返回的字符串进行一些业务验证。在这种情况下,您需要编写 2 个集成测试并确保模拟方法返回 2不同的值(虚拟值而不是达到该终点)

我们编写单元测试/集成测试的原因是为了确保您的整个代码按预期工作,但不会从您的代码中影响其他系统。

关于java - 模拟子服务的 REST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49914360/

相关文章:

java - 在 Spring java 配置中调用 @Bean 注解的方法

java - Android Spinner 对话框未填充?

java - 奇怪的 Tomcat 8 部署行为

spring-boot - ReactorNettyWebSocketClient 使用示例

linux - 即使在 session 超时后如何使 spring-boot 应用程序保持事件状态

java - 定期缓存并上传到服务器

spring - Spring-Websockets 4.2 中使用 SockJS 的部分消息

spring - gradle 在 mavenLocal 存储库中找不到 jar

spring-mvc - 为特定领域设计的 Spring Boot Web 服务

java - 将 JPanel 保存为 .jpg/.png 图像