refactor(接口测试): 优化mock执行可以带mock的期望id
This commit is contained in:
parent
782eaa88fd
commit
ce0ed0711e
|
@ -11,7 +11,7 @@ import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/mock-server/{projectNum}/{apiNum}/**")
|
@RequestMapping(value = {"/mock-server/{projectNum}/{apiNum}/{mockNum}/**", "/mock-server/{projectNum}/{apiNum}/**"})
|
||||||
@Tag(name = "接口测试-接口管理-接口定义-Mock")
|
@Tag(name = "接口测试-接口管理-接口定义-Mock")
|
||||||
@MultipartConfig
|
@MultipartConfig
|
||||||
public class MockServerController {
|
public class MockServerController {
|
||||||
|
@ -21,54 +21,54 @@ public class MockServerController {
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.OPTIONS)
|
@RequestMapping(method = RequestMethod.OPTIONS)
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> optionsRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> optionsRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return mockServerService.execute(HttpMethod.OPTIONS.name(), projectNum, apiNum, request);
|
return mockServerService.execute(HttpMethod.OPTIONS.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.HEAD)
|
@RequestMapping(method = RequestMethod.HEAD)
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> headerRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> headerRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return mockServerService.execute(HttpMethod.HEAD.name(), projectNum, apiNum, request);
|
return mockServerService.execute(HttpMethod.HEAD.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.TRACE)
|
@RequestMapping(method = RequestMethod.TRACE)
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> traceRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> traceRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return mockServerService.execute(HttpMethod.TRACE.name(), projectNum, apiNum, request);
|
return mockServerService.execute(HttpMethod.TRACE.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> getMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> getMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable(required = false) String mockNum, HttpServletRequest request) {
|
||||||
return handleMockRequest(HttpMethod.GET.name(), projectNum, apiNum, request);
|
return handleMockRequest(HttpMethod.GET.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> postMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> postMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return handleMockRequest(HttpMethod.POST.name(), projectNum, apiNum, request);
|
return handleMockRequest(HttpMethod.POST.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping
|
@PutMapping
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> putMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> putMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return handleMockRequest(HttpMethod.PUT.name(), projectNum, apiNum, request);
|
return handleMockRequest(HttpMethod.PUT.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> deleteMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> deleteMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return handleMockRequest(HttpMethod.DELETE.name(), projectNum, apiNum, request);
|
return handleMockRequest(HttpMethod.DELETE.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping
|
@PatchMapping
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
public ResponseEntity<?> patchMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> patchMockRequest(@PathVariable String projectNum, @PathVariable String apiNum, @PathVariable String mockNum, HttpServletRequest request) {
|
||||||
return handleMockRequest(HttpMethod.PATCH.name(), projectNum, apiNum, request);
|
return handleMockRequest(HttpMethod.PATCH.name(), projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<?> handleMockRequest(String method, String projectNum, String apiNum, HttpServletRequest request) {
|
private ResponseEntity<?> handleMockRequest(String method, String projectNum, String apiNum, String mockNum, HttpServletRequest request) {
|
||||||
return mockServerService.execute(method, projectNum, apiNum, request);
|
return mockServerService.execute(method, projectNum, apiNum, mockNum, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.api.dto.mockserver;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -15,8 +16,9 @@ public class keyValueMatchRule {
|
||||||
private List<KeyValueInfo> matchRules;
|
private List<KeyValueInfo> matchRules;
|
||||||
|
|
||||||
public boolean match(Map<String, String> matchParam) {
|
public boolean match(Map<String, String> matchParam) {
|
||||||
if (MapUtils.isEmpty(matchParam)) {
|
if ((MapUtils.isEmpty(matchParam) && CollectionUtils.isNotEmpty(matchRules)) ||
|
||||||
return true;
|
(CollectionUtils.isEmpty(matchRules) && MapUtils.isNotEmpty(matchParam))) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (isMatchAll) {
|
if (isMatchAll) {
|
||||||
for (KeyValueInfo matchRule : matchRules) {
|
for (KeyValueInfo matchRule : matchRules) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package io.metersphere.api.dto.request.http;
|
package io.metersphere.api.dto.request.http;
|
||||||
|
|
||||||
import io.metersphere.project.dto.environment.auth.HTTPAuthConfig;
|
|
||||||
import io.metersphere.api.dto.request.http.body.Body;
|
import io.metersphere.api.dto.request.http.body.Body;
|
||||||
import io.metersphere.plugin.api.spi.AbstractMsProtocolTestElement;
|
import io.metersphere.plugin.api.spi.AbstractMsProtocolTestElement;
|
||||||
|
import io.metersphere.project.dto.environment.auth.HTTPAuthConfig;
|
||||||
import io.metersphere.sdk.constants.HttpMethodConstants;
|
import io.metersphere.sdk.constants.HttpMethodConstants;
|
||||||
import io.metersphere.system.valid.EnumValue;
|
import io.metersphere.system.valid.EnumValue;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
@ -72,4 +72,8 @@ public class MsHTTPElement extends AbstractMsProtocolTestElement {
|
||||||
* mock执行需要的接口编号
|
* mock执行需要的接口编号
|
||||||
*/
|
*/
|
||||||
private Long num;
|
private Long num;
|
||||||
|
/**
|
||||||
|
* mock调试过来的mock编号
|
||||||
|
*/
|
||||||
|
private String mockNum;
|
||||||
}
|
}
|
|
@ -105,7 +105,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
||||||
|
|
||||||
HTTPAuthConfig authConfig = msHTTPElement.getAuthConfig();
|
HTTPAuthConfig authConfig = msHTTPElement.getAuthConfig();
|
||||||
|
|
||||||
if ((authConfig == null || !authConfig.isHTTPAuthValid()) && httpConfig != null) {
|
if ((authConfig == null || !authConfig.isHTTPAuthValid()) && httpConfig != null) {
|
||||||
authConfig = httpConfig.getAuthConfig();
|
authConfig = httpConfig.getAuthConfig();
|
||||||
}
|
}
|
||||||
// 处理认证信息
|
// 处理认证信息
|
||||||
|
@ -119,6 +119,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
||||||
* 判断是否启用环境
|
* 判断是否启用环境
|
||||||
* 非自定义请求启用
|
* 非自定义请求启用
|
||||||
* 自定义请求需要判断是否启用
|
* 自定义请求需要判断是否启用
|
||||||
|
*
|
||||||
* @param httpElement
|
* @param httpElement
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -379,7 +380,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
||||||
if (match) {
|
if (match) {
|
||||||
// 如果是mock 返回的url格式是 /mock-server/projectNum/apiNum
|
// 如果是mock 返回的url格式是 /mock-server/projectNum/apiNum
|
||||||
if (BooleanUtils.isTrue(envConfig.getMock())) {
|
if (BooleanUtils.isTrue(envConfig.getMock())) {
|
||||||
httpConfig.setHostname(StringUtils.join(httpConfig.getHostname(),"/", msHTTPElement.getNum()));
|
httpConfig.setHostname(StringUtils.join(httpConfig.getHostname(), "/", msHTTPElement.getNum(), StringUtils.isNotBlank(msHTTPElement.getMockNum()) ? "/" + msHTTPElement.getMockNum() : StringUtils.EMPTY));
|
||||||
}
|
}
|
||||||
return httpConfig;
|
return httpConfig;
|
||||||
}
|
}
|
||||||
|
@ -421,7 +422,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
||||||
.filter(KeyValueParam::isValid)
|
.filter(KeyValueParam::isValid)
|
||||||
.filter(header ->
|
.filter(header ->
|
||||||
StringUtils.equalsIgnoreCase(header.getKey().trim(), ApiConstants.CONTENT_TYPE)
|
StringUtils.equalsIgnoreCase(header.getKey().trim(), ApiConstants.CONTENT_TYPE)
|
||||||
&& StringUtils.contains(header.getValue(), contentType)
|
&& StringUtils.contains(header.getValue(), contentType)
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
// 不包含则添加一个
|
// 不包含则添加一个
|
||||||
|
@ -475,7 +476,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
||||||
return stringBuffer.substring(0, stringBuffer.length() - 1);
|
return stringBuffer.substring(0, stringBuffer.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DNSCacheManager getEnvDns(String name , EnvironmentInfoDTO envConfig, HttpConfig httpConfig) {
|
private DNSCacheManager getEnvDns(String name, EnvironmentInfoDTO envConfig, HttpConfig httpConfig) {
|
||||||
if (envConfig == null ||
|
if (envConfig == null ||
|
||||||
envConfig.getConfig() == null ||
|
envConfig.getConfig() == null ||
|
||||||
envConfig.getConfig().getHostConfig() == null ||
|
envConfig.getConfig().getHostConfig() == null ||
|
||||||
|
|
|
@ -215,11 +215,6 @@ public class ApiDefinitionImportUtilService {
|
||||||
ApiDetailWithDataUpdate apiDetailWithDataUpdate = new ApiDetailWithDataUpdate();
|
ApiDetailWithDataUpdate apiDetailWithDataUpdate = new ApiDetailWithDataUpdate();
|
||||||
getNeedUpdateData(request, apiDealWithData, apiDetailWithDataUpdate);
|
getNeedUpdateData(request, apiDealWithData, apiDetailWithDataUpdate);
|
||||||
|
|
||||||
//不用的数据清空,保证内存回收
|
|
||||||
apiLists = new ArrayList<>();
|
|
||||||
apiModules = new ArrayList<>();
|
|
||||||
importData = new ArrayList<>();
|
|
||||||
|
|
||||||
List<LogDTO> operationLogs = new ArrayList<>();
|
List<LogDTO> operationLogs = new ArrayList<>();
|
||||||
//数据入库
|
//数据入库
|
||||||
insertData(modulePathMap, idModuleMap, apiDetailWithDataUpdate, request, operationLogs);
|
insertData(modulePathMap, idModuleMap, apiDetailWithDataUpdate, request, operationLogs);
|
||||||
|
@ -229,7 +224,7 @@ public class ApiDefinitionImportUtilService {
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void batchSaveLog(List<LogDTO> operationLogs) {
|
public void batchSaveLog(List<LogDTO> operationLogs) {
|
||||||
SubListUtils.dealForSubList(operationLogs, 100, operationLogService::batchAdd);
|
operationLogService.batchAdd(operationLogs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getNextOrder(String projectId) {
|
public Long getNextOrder(String projectId) {
|
||||||
|
|
|
@ -62,9 +62,10 @@ public class MockServerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ResponseEntity<?> execute(String method, String projectNum, String apiNum, HttpServletRequest request) {
|
public ResponseEntity<?> execute(String method, String projectNum, String apiNum, String mockNum, HttpServletRequest request) {
|
||||||
var requestHeaderMap = MockServerUtils.getHttpRequestHeader(request);
|
var requestHeaderMap = MockServerUtils.getHttpRequestHeader(request);
|
||||||
String url = request.getRequestURL().toString();
|
String url = request.getRequestURL().toString();
|
||||||
|
//判断根据mockNum是否可以找到对应的mock配置 如果找不到,需要拿接口下所有的mock配置进行匹配
|
||||||
String requestUrlSuffix = MockServerUtils.getUrlSuffix(StringUtils.joinWith("/", "/mock-server", projectNum, apiNum), request);
|
String requestUrlSuffix = MockServerUtils.getUrlSuffix(StringUtils.joinWith("/", "/mock-server", projectNum, apiNum), request);
|
||||||
|
|
||||||
// Try to find API definition based on projectNum and apiNum
|
// Try to find API definition based on projectNum and apiNum
|
||||||
|
@ -80,6 +81,13 @@ public class MockServerService {
|
||||||
return requestNotFound();
|
return requestNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(mockNum) && mockNum.startsWith(apiNum)) {
|
||||||
|
requestUrlSuffix = MockServerUtils.getUrlSuffix(StringUtils.joinWith("/", "/mock-server", projectNum, apiNum, mockNum), request);
|
||||||
|
} else {
|
||||||
|
mockNum = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check if method and path match the API definition
|
// Check if method and path match the API definition
|
||||||
if (!StringUtils.equalsIgnoreCase(method, apiDefinition.getMethod()) || !MockServerUtils.checkUrlMatch(apiDefinition.getPath(), requestUrlSuffix)) {
|
if (!StringUtils.equalsIgnoreCase(method, apiDefinition.getMethod()) || !MockServerUtils.checkUrlMatch(apiDefinition.getPath(), requestUrlSuffix)) {
|
||||||
return requestNotFound();
|
return requestNotFound();
|
||||||
|
@ -89,7 +97,7 @@ public class MockServerService {
|
||||||
HttpRequestParam requestMockParams = MockServerUtils.getHttpRequestParam(request, requestUrlSuffix, apiDefinition.getPath(), !isUrlParamMethod(method));
|
HttpRequestParam requestMockParams = MockServerUtils.getHttpRequestParam(request, requestUrlSuffix, apiDefinition.getPath(), !isUrlParamMethod(method));
|
||||||
LogUtils.info("Mock [" + url + "] Header:{}", requestHeaderMap);
|
LogUtils.info("Mock [" + url + "] Header:{}", requestHeaderMap);
|
||||||
LogUtils.info("Mock [" + url + "] request:{}", JSON.toJSONString(requestMockParams));
|
LogUtils.info("Mock [" + url + "] request:{}", JSON.toJSONString(requestMockParams));
|
||||||
ApiMockConfigDTO compareMockConfig = findMatchingMockConfig(apiDefinition.getId(), requestHeaderMap, requestMockParams);
|
ApiMockConfigDTO compareMockConfig = findMatchingMockConfig(apiDefinition.getId(), requestHeaderMap, requestMockParams, mockNum);
|
||||||
|
|
||||||
if (compareMockConfig != null && !compareMockConfig.isEnable()) {
|
if (compareMockConfig != null && !compareMockConfig.isEnable()) {
|
||||||
return requestNotFound();
|
return requestNotFound();
|
||||||
|
@ -111,10 +119,13 @@ public class MockServerService {
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiMockConfigDTO findMatchingMockConfig(String apiId, Map<String, String> requestHeaderMap, HttpRequestParam param) {
|
private ApiMockConfigDTO findMatchingMockConfig(String apiId, Map<String, String> requestHeaderMap, HttpRequestParam param, String mockNum) {
|
||||||
// 查询符合条件的 ApiDefinitionMockConfig 列表
|
// 查询符合条件的 ApiDefinitionMockConfig 列表
|
||||||
ApiDefinitionMockExample mockExample = new ApiDefinitionMockExample();
|
ApiDefinitionMockExample mockExample = new ApiDefinitionMockExample();
|
||||||
mockExample.createCriteria().andApiDefinitionIdEqualTo(apiId);
|
mockExample.createCriteria().andApiDefinitionIdEqualTo(apiId);
|
||||||
|
if (StringUtils.isNotBlank(mockNum)) {
|
||||||
|
mockExample.getOredCriteria().forEach(criteria -> criteria.andExpectNumEqualTo(mockNum));
|
||||||
|
}
|
||||||
List<ApiDefinitionMock> apiDefinitionMockList = apiDefinitionMockMapper.selectByExample(mockExample);
|
List<ApiDefinitionMock> apiDefinitionMockList = apiDefinitionMockMapper.selectByExample(mockExample);
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(apiDefinitionMockList)) {
|
if (CollectionUtils.isEmpty(apiDefinitionMockList)) {
|
||||||
|
|
|
@ -1250,6 +1250,12 @@ public class ApiDefinitionMockControllerTests extends BaseTest {
|
||||||
MockHttpServletRequestBuilder requestBuilder = mockServerTestService.getRequestBuilder("GET", url);
|
MockHttpServletRequestBuilder requestBuilder = mockServerTestService.getRequestBuilder("GET", url);
|
||||||
ResultActions action = mockMvc.perform(requestBuilder);
|
ResultActions action = mockMvc.perform(requestBuilder);
|
||||||
MockHttpServletResponse mockServerResponse = action.andReturn().getResponse();
|
MockHttpServletResponse mockServerResponse = action.andReturn().getResponse();
|
||||||
|
url = "/" + mockServerDomain + "/100001/" + apiDefinition.getNum() + "/" + mockData.getExpectNum() + apiDefinition.getPath();
|
||||||
|
|
||||||
|
//开始创建请求
|
||||||
|
requestBuilder = mockServerTestService.getRequestBuilder("GET", url);
|
||||||
|
action = mockMvc.perform(requestBuilder);
|
||||||
|
mockServerResponse = action.andReturn().getResponse();
|
||||||
//判断响应
|
//判断响应
|
||||||
mockServerResponse.getContentAsString(StandardCharsets.UTF_8);
|
mockServerResponse.getContentAsString(StandardCharsets.UTF_8);
|
||||||
mockData.setEnable(false);
|
mockData.setEnable(false);
|
||||||
|
|
Loading…
Reference in New Issue