Skip to content

Commit

Permalink
feat: 支持泛型mock返回
Browse files Browse the repository at this point in the history
  • Loading branch information
yinjihuan committed May 6, 2022
1 parent 7647f98 commit fd6e6a2
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 19 deletions.
8 changes: 5 additions & 3 deletions agent.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# mock文件路径
foxMockFilePath=/Users/yinjihuan/Downloads/foxmockdata
foxMockFilePath=/Users/yinjihuan/Documents/foxmockdata
# foxmock的agent jar包路径,不填默认为当前文件夹
foxMockAgentJarPath=fox-mock-agent/target/fox-mock-agent-2.0-SNAPSHOT.jar
foxMockAgentJarPath=fox-mock-agent/target/fox-mock-agent-3.0.jar
# mock方法白名单,如果文件夹中有多个方法会被全部mock,如果指定了此配置将只会mock这里指定的方法
mockMethodWhiteList=com.cxytiandi.foxmock.example.UserService#getAge|com.cxytiandi.foxmock.example.UserService#getAddrs
#mockMethodWhiteList=com.cxytiandi.foxmock.example.UserService#getAge|com.cxytiandi.foxmock.example.UserService#getName2
# httpn mock数据地址,可以对接配置中心,必须是get请求
#mockDataHttpUrl=http%3A%2F%2F47.105.66.210%3A8848%2Fnacos%2Fv1%2Fcs%2Fconfigs%3FdataId%3Dfox-mock%26group%3DDEFAULT_GROUP%26tenant%3D9c9f5197-688c-4ef9-ae68-1ff28663301d
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
*/
public class FoxMockAgent {

static {
System.setProperty("arthas.logback.configurationFile", "foxmock-logback.xml");
}

private static final Logger LOG = LoggerFactory.getLogger(FoxMockAgent.class);

private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
if (Objects.nonNull(data)) {
match = true;
LOG.info(String.format("mock methods %s, mock data is %s", key, data));
String mockCode = "if(true){com.cxytiandi.foxmock.agent.gson.Gson gson = new com.cxytiandi.foxmock.agent.gson.Gson();return ($r)gson.fromJson(%s, $type);}";
method.insertBefore(String.format(mockCode, new Gson().toJson(data)));
String mockCode = "if(true){" +
"return ($r)com.cxytiandi.foxmock.agent.utils.JsonUtils.parse(%s,%s,%s);" +
"}";
method.insertBefore(String.format(mockCode, new Gson().toJson(data), "\""+className+"\"", "\""+methodName+"\""));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.cxytiandi.foxmock.agent.utils;

import com.google.gson.Gson;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

/**
* JSON转换工具类,由于javassist不支持泛型,所以采用了一个折中的方式,在这里处理好带泛型的对象
*
* @作者 尹吉欢
* @个人微信 jihuan900
* @微信公众号 猿天地
* @GitHub https://github.com/yinjihuan
* @作者介绍 http://cxytiandi.com/about
* @时间 2022-05-06 21:20
*/
public class JsonUtils {

public static Object parse(String data, String className, String methodName) {
try {
Type genericReturnType = null;
Class<?> clazz = Class.forName(className.replace('/','.'));
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method m: declaredMethods) {
if (m.getName().equals(methodName)){
genericReturnType = m.getGenericReturnType();
break;
}
}

Gson gson = new Gson();
Object value = gson.fromJson(data, genericReturnType);
return value;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void main(String[] args) {
String mockDataHttpUrl = config.getProperty("mockDataHttpUrl", "");

if (Objects.isNull(foxMockAgentJarPath)) {
foxMockAgentJarPath = PathUtils.getAgentPath() + File.separator + "fox-mock-agent-2.0.jar";
foxMockAgentJarPath = PathUtils.getAgentPath() + File.separator + "fox-mock-agent-3.0.jar";
}

VirtualMachine attach = VirtualMachine.attach(String.valueOf(getPid()));
Expand Down
23 changes: 23 additions & 0 deletions fox-mock-example/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,33 @@

<artifactId>fox-mock-example</artifactId>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- <exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>-->
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.cxytiandi.foxmock.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Map;
import java.util.Objects;

/**
* @作者 尹吉欢
Expand All @@ -9,22 +13,33 @@
* @作者介绍 http://cxytiandi.com/about
* @时间 2022-04-18 22:11
*/
@SpringBootApplication
public class FoxMockApp {

public static void main(String[] args) throws Exception {
while (true) {
UserService userService = new UserService();
System.out.println(String.format("你好 %s", userService.getName2().getId()));
System.out.println(String.format("你好 %s", userService.getAge()));
System.out.println(String.format("你好 %s", userService.getAddrs()));
System.out.println(String.format("你好 %s", userService.getUsers()));
System.out.println(String.format("你好 %s", userService.getUsers2()));
System.out.println(String.format("你好 %s", userService.getUser()));
System.out.println(String.format("你好 %s", userService.getUserDetail()));
System.out.println("----------------------------------------");
Thread.sleep(5000);
}
SpringApplication.run(FoxMockApp.class);

while (true) {
UserService userService = new UserService();
System.out.println(String.format("你好 %s", userService.getName2().getId()));
System.out.println(String.format("你好 %s", userService.getAge()));
System.out.println(String.format("你好 %s", userService.getAddrs()));
System.out.println(String.format("你好 %s", userService.getUsers()));
System.out.println(String.format("你好 %s", userService.getUsers2()));
System.out.println(String.format("你好 %s", userService.getUser()));
System.out.println(String.format("你好 %s", userService.getUserDetail()));
// 泛型测试
Result<UserDetail> userDetailResult = userService.getUserDetail();
UserDetail userDetail = userDetailResult.getData();
if (Objects.nonNull(userDetail)) {
Map<String, UserDetail.UserAddress> addressMap = userDetail.getAddressMap();
addressMap.forEach((k,v) -> {
System.out.println(k + "\t" + v.getAddress());
});
}

System.out.println("----------------------------------------");
Thread.sleep(5000);
}
}

}

0 comments on commit fd6e6a2

Please sign in to comment.