微服务架构下的自动化测试全链路设计思路分析
Posted 分布式实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务架构下的自动化测试全链路设计思路分析相关的知识,希望对你有一定的参考价值。
given(marketingService.mixMarketingActivity(anyObject())).willReturn(stubResponse);
RuleCalculateResponse response = this.ruleCalculatorBiz.ruleCalculate(request);
public interface CCMarketingCentralFacade {
CallResponse callMarketingCentral(CallRequest request);
}
public interface ClassMarketingCentralFacade {
CallResponse callMarketingCentral(CallRequest request);
}
public class CCMarketingCentralFacadeMocker implements CCMarketingCentralFacade {
@Override
public CallResponse callMarketingCentral(CallRequest request) {
CallResponse response = ...
MarketingResultDto marketingResultDto = ...
marketingResultDto.setTotalDiscount(new BigDecimal("90.19"));
marketingResultDto.setUseTotalDiscount(true);
response.getData().setMarketingResult(marketingResultDto);
return response;
}
}
public class ClassMarketingCentralFacadeMocker implements ClassMarketingCentralFacade {
@Override
public CallResponse callMarketingCentral(CallRequest request) {
CallResponse response = ...
MarketingResultDto marketingResultDto = ...
marketingResultDto.setUseCoupon(true);
marketingResultDto.setTotalDiscount(null);
marketingResultDto.setUseTotalDiscount(false);
List<MarketingProductDiscountDto> discountDtos = ...
request.getMarketingProductTagsParameter().getMarketingTags().forEach(item -> {
MarketingProductDiscountDto discountDto = ...
discountDto.setProductId(item.getProductID());
...
discountDtos.add(discountDto);
});
...
return response;
}
}
public abstract class BaseRequest implements Serializable {
public MockParameter mockParameter;
}
public class MockParameter {
/**
* mock cc 营销调用接口
*/
public Boolean mockCCMarketingInterface;
/**
* mock class 营销调用接口
*/
public Boolean mockClassMarketingInterface;
/**
* 是否自动化测试 mock
*/
public Boolean useAutoTestMock;
/**
* 测试mock参数
*/
public String testMockParam;
}
@Value("${marketing.cloud.business.access.url.mock}")
private String mockUrl;
/**
* 自动化测试 mocker bean
*/
@Bean("CCMarketingCentralFacadeTestMock")
public CCMarketingCentralFacade CCMarketingCentralFacadeTestMock() {
RestClientProxyFactoryBean<CCMarketingCentralFacade> restClientProxyFactoryBean ...
restClientProxyFactoryBean.setBaseUri(this.mockUrl);
...
}
/**
* 自动化测试 mocker bean
*/
@Bean("ClassMarketingCentralFacadeTestMock")
public ClassMarketingCentralFacade ClassMarketingCentralFacadeTestMock() {
RestClientProxyFactoryBean<ClassMarketingCentralFacade> restClientProxyFactoryBean ...
restClientProxyFactoryBean.setBaseUri(this.mockUrl);
...
}
public abstract class BaseRequest implements Serializable {
public MockParameter mockParameter;
}
@Component
@Path("v1/calculator/")
public class RuleCalculatorFacadeImpl extends BaseFacade implements RuleCalculatorFacade {
@MockFacade(Setting = MockFacade.SETTING_REQUEST_MOCK_PARAMETER)
public RuleCalculateResponse ruleCalculate(RuleCalculateRequest request) {
...
}
}
@Component
public class MarketingServiceImpl extends MarketingBaseService implements MarketingService {
@MockFacade(Setting = MockFacade.SETTING_FACADE_MOCK_BEAN)
public MarketingResult onlyExtendMarketingActivity(Marketing..Parameter tagsParameter) {
...
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MockFacade {
String SETTING_REQUEST_MOCK_PARAMETER = "setting_request_mock_parameter";
String SETTING_FACADE_MOCK_BEAN = "setting_facade_mock_bean";
String Setting();
}
@Aspect
@Component
@Slf4j
public class MockMarketingFacadeInterceptor {
@Before("@annotation(mockFacade)")
public void beforeMethod(JoinPoint joinPoint, MockFacade mockFacade) {
String settingName = mockFacade.Setting();
if (MockFacade.SETTING_REQUEST_MOCK_PARAMETER.equals(settingName)) {
Object[] args = joinPoint.getArgs();
if (args == null) return;
List<Object> argList = Arrays.asList(args);
argList.forEach(item -> {
if (item instanceof BaseRequest) {
BaseRequest request = (BaseRequest) item;
if (request.getMockParameter() != null) {
MarketingBaseService.mockParameterThreadLocal.set(request.getMockParameter());
log.info("----setting mock parameter:{}", JSON.toJSONString(request.getMockParameter()));
}
}
});
} else if (MockFacade.SETTING_FACADE_MOCK_BEAN.equals(settingName)) {
MarketingBaseService marketingBaseService = (MarketingBaseService) joinPoint.getThis();
marketingBaseService.mockBean();
log.info("----setting mock bean.");
}
}
@After("@annotation(mockFacade)")
public void afterMethod(JoinPoint joinpoint, MockFacade mockFacade) {
if (MockFacade.SETTING_FACADE_MOCK_BEAN.equals(mockFacade.Setting())) {
MarketingBaseService marketingBaseService = (MarketingBaseService) joinpoint.getThis();
marketingBaseService.mockRemove();
log.info("----remove mock bean.");
}
if (MockFacade.SETTING_REQUEST_MOCK_PARAMETER.equals(mockFacade.Setting())) {
MarketingBaseService.mockParameterThreadLocal.remove();
log.info("----remove ThreadLocal. ThreadLocal get {}", MarketingBaseService.mockParameterThreadLocal.get());
}
}
}
public abstract class MarketingBaseService extends BaseService {
protected ClassMarketingCentralFacade classMarketingCentralFacade;
protected CCMarketingCentralFacade ccMarketingCentralFacade;
public static ThreadLocal<MockParameter> mockParameterThreadLocal = new ThreadLocal<>();
public void mockBean() {
MockParameter mockParameter = mockParameterThreadLocal.get();
if (mockParameter != null && mockParameter.mockClassMarketingInterface) {
if (mockParameter.useAutoTestingMock) {
this.setClassMarketingCentralFacade(SpringContextHolder.getBean("ClassMarketingCentralFacadeTestMock", ClassMarketingCentralFacade.class));
} else {
this.setClassMarketingCentralFacade(SpringContextHolder.getBean("ClassMarketingCentralFacadeMocker", ClassMarketingCentralFacadeMocker.class));
}
} else {
this.setClassMarketingCentralFacade(SpringContextHolder.getBean("ClassMarketingCentralFacade", ClassMarketingCentralFacade.class));
}
if (mockParameter != null && mockParameter.mockCCMarketingInterface) {
if (mockParameter.useAutoTestingMock) {
this.setCcMarketingCentralFacade(SpringContextHolder.getBean("CCMarketingCentralFacadeTestMock", CCMarketingCentralFacade.class));
} else {
this.setCcMarketingCentralFacade(SpringContextHolder.getBean("CCMarketingCentralFacadeMocker", CCMarketingCentralFacadeMocker.class));
}
} else {
this.setCcMarketingCentralFacade(SpringContextHolder.getBean("CCMarketingCentralFacade", CCMarketingCentralFacade.class));
}
}
public void mockRemove() {
mockParameterThreadLocal.remove();
}
}
@Component
public class MockHttpHeadSetting implements ClientRequestFilter {
@Override
public void filter(ClientRequestContext requestContext) throws IOException {
MultivaluedMap<String, Object> header = requestContext.getHeaders();
MockParameter mockParameter = MarketingBaseService.mockParameterThreadLocal.get();
if (mockParameter != null && StringUtils.isNotBlank(mockParameter.getTestingMockParam())) {
header.add("Mock-parameter", mockParameter.getTestingMockParam());
}
}
}
com.hujiang.marketingcloud.ruleengine.service.MockHttpHeadSetting
以上是关于微服务架构下的自动化测试全链路设计思路分析的主要内容,如果未能解决你的问题,请参考以下文章
基于Pinpoint对SpringCloud微服务项目实现全链路监控 #yyds干货盘点#