使用Spring Boot对REST URL进行集成测试

我们正在构建一个具有REST接口的Spring Boot应用程序,并且在某个时候我们想测试我们的REST接口,并在可能的情况下将此测试与常规单元测试集成。 一种方法是@Autowire我们的REST控制器,并使用它来调用我们的端点。 但是,这不会完全融合,因为它将跳过JSON反序列化和全局异常处理之类的事情。 因此,对我们而言,理想的情况是在单元测试开始时启动应用程序,并在上一次单元测试后再次关闭它。

碰巧的是,Spring Boot用一个注释为我们完成了所有工作: @IntegrationTest

这是一个抽象类的示例实现,您可以将其用于单元测试,该类将在启动单元测试,缓存并最终关闭之前自动启动应用程序。

package demo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import com.fasterxml.jackson.databind.ObjectMapper;

@RunWith(SpringJUnit4ClassRunner.class)
// Your spring configuration class containing the @EnableAutoConfiguration
// annotation
@SpringApplicationConfiguration(classes = Application.class)
// Makes sure the application starts at a random free port, caches it throughout
// all unit tests, and closes it again at the end.
@IntegrationTest("server.port:0")
@WebAppConfiguration
public abstract class AbstractIntegrationTest {

	// Will contain the random free port number
	@Value("${local.server.port}")
	private int port;

	/**
	 * Returns the base url for your rest interface
	 * 
	 * @return
	 */
	private String getBaseUrl() {
		return "http://localhost:" + port;
	}

	// Some convenience methods to help you interact with your rest interface

	/**
	 * @param requestMappingUrl
	 *            should be exactly the same as defined in your RequestMapping
	 *            value attribute (including the parameters in {})
	 *            RequestMapping(value = yourRestUrl)
	 * @param serviceReturnTypeClass
	 *            should be the the return type of the service
	 * @param parametersInOrderOfAppearance
	 *            should be the parameters of the requestMappingUrl ({}) in
	 *            order of appearance
	 * @return the result of the service, or null on error
	 */
	protected <T> T getEntity(final String requestMappingUrl, final Class<T> serviceReturnTypeClass, final Object... parametersInOrderOfAppearance) {
		// Make a rest template do do the service call
		final TestRestTemplate restTemplate = new TestRestTemplate();
		// Add correct headers, none for this example
		final HttpEntity<String> requestEntity = new HttpEntity<String>(new HttpHeaders());
		try {
			// Do a call the the url
			final ResponseEntity<T> entity = restTemplate.exchange(getBaseUrl() + requestMappingUrl, HttpMethod.GET, requestEntity, serviceReturnTypeClass,
					parametersInOrderOfAppearance);
			// Return result
			return entity.getBody();
		} catch (final Exception ex) {
			// Handle exceptions
		}
		return null;
	}

	/**
	 * @param requestMappingUrl
	 *            should be exactly the same as defined in your RequestMapping
	 *            value attribute (including the parameters in {})
	 *            RequestMapping(value = yourRestUrl)
	 * @param serviceListReturnTypeClass
	 *            should be the the generic type of the list the service
	 *            returns, eg: List<serviceListReturnTypeClass>
	 * @param parametersInOrderOfAppearance
	 *            should be the parameters of the requestMappingUrl ({}) in
	 *            order of appearance
	 * @return the result of the service, or null on error
	 */
	protected <T> List<T> getList(final String requestMappingUrl, final Class<T> serviceListReturnTypeClass, final Object... parametersInOrderOfAppearance) {
		final ObjectMapper mapper = new ObjectMapper();
		final TestRestTemplate restTemplate = new TestRestTemplate();
		final HttpEntity<String> requestEntity = new HttpEntity<String>(new HttpHeaders());
		try {
			// Retrieve list
			final ResponseEntity<List> entity = restTemplate.exchange(getBaseUrl() + requestMappingUrl, HttpMethod.GET, requestEntity, List.class, parametersInOrderOfAppearance);
			final List<Map<String, String>> entries = entity.getBody();
			final List<T> returnList = new ArrayList<T>();
			for (final Map<String, String> entry : entries) {
				// Fill return list with converted objects
				returnList.add(mapper.convertValue(entry, serviceListReturnTypeClass));
			}
			return returnList;
		} catch (final Exception ex) {
			// Handle exceptions
		}
		return null;
	}

	/**
	 * 
	 * @param requestMappingUrl
	 *            should be exactly the same as defined in your RequestMapping
	 *            value attribute (including the parameters in {})
	 *            RequestMapping(value = yourRestUrl)
	 * @param serviceReturnTypeClass
	 *            should be the the return type of the service
	 * @param objectToPost
	 *            Object that will be posted to the url
	 * @return
	 */
	protected <T> T postEntity(final String requestMappingUrl, final Class<T> serviceReturnTypeClass, final Object objectToPost) {
		final TestRestTemplate restTemplate = new TestRestTemplate();
		final ObjectMapper mapper = new ObjectMapper();
		try {
			final HttpEntity<String> requestEntity = new HttpEntity<String>(mapper.writeValueAsString(objectToPost));
			final ResponseEntity<T> entity = restTemplate.postForEntity(getBaseUrl() + requestMappingUrl, requestEntity, serviceReturnTypeClass);
			return entity.getBody();
		} catch (final Exception ex) {
			// Handle exceptions
		}
		return null;
	}
}

翻译自: https://www.javacodegeeks.com/2015/03/integration-testing-on-rest-urls-with-spring-boot.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值