refactor(接口测试): 支持动态注册子组件

This commit is contained in:
fit2-zhao 2023-11-03 18:32:58 +08:00 committed by Craftsman
parent 7e5a86f881
commit f34c916760
3 changed files with 73 additions and 15 deletions

View File

@ -9,6 +9,5 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@PluginSubType("MsLoopController")
public class MsLoopController extends TestElementDTO {
private String clazzName = MsLoopController.class.getCanonicalName();
private String loopType;
}

View File

@ -9,7 +9,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver;
import com.fasterxml.jackson.databind.type.CollectionType;
import io.metersphere.sdk.dto.api.request.post.processors.MsPostJSR223Processor;
import io.metersphere.sdk.dto.api.request.sampler.MsDebugSampler;
@ -24,18 +23,23 @@ public class ApiDataUtils {
private ApiDataUtils() {
}
private static final ObjectMapper objectMapper = JsonMapper.builder()
private static ObjectMapper objectMapper = JsonMapper.builder()
.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
.build();
private static final StdSubtypeResolver resolver = new StdSubtypeResolver();
// 默认内置子组件如果有新的子组件需要在这里添加
static final List<NamedType> namedTypes = new LinkedList<>();
static {
// 添加处理资源文件的类
final List<NamedType> namedTypes = new LinkedList<>();
// 默认内置的子组件
namedTypes.add(new NamedType(MsPostJSR223Processor.class, MsPostJSR223Processor.class.getSimpleName()));
namedTypes.add(new NamedType(MsDebugSampler.class, MsDebugSampler.class.getSimpleName()));
setObjectMapper(objectMapper);
namedTypes.forEach(objectMapper::registerSubtypes);
}
private static void setObjectMapper(ObjectMapper objectMapper) {
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 支持json字符中带注释符
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
@ -44,8 +48,6 @@ public class ApiDataUtils {
// 如果一个对象中没有任何的属性那么在序列化的时候就会报错
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
namedTypes.forEach(resolver::registerSubtypes);
objectMapper.setSubtypeResolver(resolver);
}
public static String toJSONString(Object value) {
@ -88,11 +90,23 @@ public class ApiDataUtils {
/**
* 设置动态加载的jar的Resolver
*
* @param namedTypes PluginSubType 注解的类
* @param newTypes PluginSubType 注解的类
*/
public static void setResolver(List<NamedType> namedTypes) {
namedTypes.forEach(resolver::registerSubtypes);
objectMapper.setSubtypeResolver(resolver);
public static void setResolver(List<NamedType> newTypes) {
// 获取所有子组件 TODO此方法无法卸载组件
// SubtypeResolver subtypeResolver = objectMapper.getSubtypeResolver();
// objectMapper.setSubtypeResolver(subtypeResolver);
objectMapper = JsonMapper.builder()
.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
.build();
setObjectMapper(objectMapper);
// 加入默认组件
namedTypes.forEach(objectMapper::registerSubtypes);
// 加入新的动态组件
newTypes.forEach(objectMapper::registerSubtypes);
}
/**
@ -101,7 +115,8 @@ public class ApiDataUtils {
* @param clazz PluginSubType 注解的类
*/
public static void setResolver(Class<?> clazz) {
resolver.registerSubtypes(clazz);
objectMapper.setSubtypeResolver(resolver);
setResolver(new LinkedList<>());
// 加入新的动态组件
objectMapper.registerSubtypes(clazz);
}
}

View File

@ -1,7 +1,9 @@
package io.metersphere.api.controller;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import io.metersphere.api.util.ApiDataUtils;
import io.metersphere.plugin.api.dto.TestElementDTO;
import io.metersphere.sdk.dto.api.request.logic.controller.MsLoopController;
import io.metersphere.sdk.dto.api.request.post.processors.MsPostJSR223Processor;
import io.metersphere.sdk.dto.api.request.sampler.MsDebugSampler;
import io.metersphere.system.uid.IDGenerator;
@ -10,13 +12,15 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest;
import java.util.LinkedList;
import java.util.List;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class PluginSubTypeTests {
@Test
@Order(0)
public void pluginSubTypeTest() throws Exception {
@ -35,4 +39,44 @@ public class PluginSubTypeTests {
TestElementDTO testElementDTO = ApiDataUtils.parseObject(json, TestElementDTO.class);
Assertions.assertNotNull(testElementDTO);
}
@Test
@Order(1)
public void resolverTest() throws Exception {
// ApiDataUtils.setResolver(MsLoopController.class);
List<NamedType> namedTypes = new LinkedList<>();
namedTypes.add(new NamedType(MsLoopController.class, MsLoopController.class.getSimpleName()));
ApiDataUtils.setResolver(namedTypes);
}
@Test
@Order(2)
public void newPluginSubTypeTest() throws Exception {
MsLoopController loopController = new MsLoopController();
loopController.setName("测试loopController");
String json = ApiDataUtils.toJSONString(loopController);
TestElementDTO testElementDTO = ApiDataUtils.parseObject(json, TestElementDTO.class);
Assertions.assertNotNull(testElementDTO);
}
@Test
@Order(3)
public void retrySubTypeTest() throws Exception {
MsDebugSampler debugSampler = new MsDebugSampler();
debugSampler.setName("测试DebugSampler");
debugSampler.setUuid(IDGenerator.nextStr());
LinkedList<TestElementDTO> hashTree = new LinkedList<>();
hashTree.add(debugSampler);
MsPostJSR223Processor msjsr223Processor = new MsPostJSR223Processor();
msjsr223Processor.setName("测试jsr223");
msjsr223Processor.setJsrEnable(true);
msjsr223Processor.setChildren(hashTree);
String json = ApiDataUtils.toJSONString(msjsr223Processor);
Assertions.assertNotNull(json);
TestElementDTO testElementDTO = ApiDataUtils.parseObject(json, TestElementDTO.class);
Assertions.assertNotNull(testElementDTO);
}
}