一尘不染

使用RestTemplate进行RESTful Services测试

spring-boot

在我的应用程序中,我有很多REST服务。我已经针对所有服务编写了测试:

org.springframework.web.client.RestTemplate

REST服务调用例如如下所示:

final String loginResponse = restTemplate.exchange("http://localhost:8080/api/v1/xy", HttpMethod.POST, httpEntity, String.class)
        .getBody();

然后我检查响应正文-一切正常。缺点是必须确保启动应用程序才能调用REST服务。

我现在的问题是如何在JUnit- @Test方法中执行此操作?它是一个Spring Boot应用程序(带有嵌入式tomcat)。

感谢帮助!


阅读 289

收藏
2020-05-30

共1个答案

一尘不染

文档中有一很好的章节,建议您通读它以完全理解您可以做什么。

我喜欢使用@IntegrationTest自定义配置,因为它可以启动整个服务器并允许您测试整个系统。如果要用模拟替换系统的某些部分,可以通过排除某些配置或bean并用自己的替换来实现。

这是一个小例子。我省略了该MessageService接口,因为它从功能上显而易见IndexController,并且是默认实现DefaultMessageService--因为它不相关。

它的作用是将整个应用程序减至最小,DefaultMessageService但将其自身MessageService保留。然后,它RestTemplate用于在测试用例中向正在运行的应用程序发出实际的HTTP请求。

应用类别:

IntegrationTestDemo.java:

@SpringBootApplication
public class IntegrationTestDemo {

    public static void main(String[] args) {
        SpringApplication.run(IntegrationTestDemo.class, args);
    }

}

IndexController.java:

@RestController
public class IndexController {

    @Autowired
    MessageService messageService;

    @RequestMapping("/")
    String getMessage() {
        return messageService.getMessage();
    }
}

测试类别:

IntegrationTestDemoTest.java:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfig.class)
@WebIntegrationTest // This will start the server on a random port
public class IntegrationTestDemoTest {

    // This will hold the port number the server was started on
    @Value("${local.server.port}")
    int port;

    final RestTemplate template = new RestTemplate();

    @Test
    public void testGetMessage() {
        String message = template.getForObject("http://localhost:" + port + "/", String.class);

        Assert.assertEquals("This is a test message", message);
    }
}

TestConfig.java:

@SpringBootApplication
@ComponentScan(
    excludeFilters = {
        // Exclude the default message service
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DefaultMessageService.class),
        // Exclude the default boot application or it's
        // @ComponentScan will pull in the default message service
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = IntegrationTestDemo.class)
    }
)
public class TestConfig {

    @Bean
    // Define our own test message service
    MessageService mockMessageService() {
        return new MessageService() {
            @Override
            public String getMessage() {
                return "This is a test message";
            }
        };
    }
}
2020-05-30