jsonzou / jmockdata Goto Github PK
View Code? Open in Web Editor NEWThe plugin to mock the java data by random.
License: Apache License 2.0
The plugin to mock the java data by random.
License: Apache License 2.0
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.LocalDateTime" on path: DexPathList[[zip file
最新版适配了java.time.LocalDateTime
但是低版本的jdk不支持
是否切换到上一个版本就能解决问题呢
MockConfig mockConfig = new MockConfig();
mockConfig.intRange(-1,1);
mockConfig.intRange(0,1);
都会报错
OuterBean
public class OuterBean<T> {
private T result;
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
}
ArrayBean
public class ArrayBean<T> {
private List<T> list;
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
代码
OuterBean<ArrayBean<BasicBean>> outerBean = JMockData.mock(new TypeReference<OuterBean<ArrayBean<BasicBean>>>() {
});
MockConfig.init修改如下
public MockConfig init(Type type) {
if (!(type instanceof ParameterizedType)) {
return this;
}
ParameterizedType paramType = ((ParameterizedType) type);
Class<?> clazz = (Class<?>) paramType.getRawType();
Type[] types = paramType.getActualTypeArguments();
Class<?> supperClazz = clazz;
while (supperClazz != null && !ReflectionUtils.isSystemClass(clazz.getName())) {
TypeVariable<?>[] typeVariables = supperClazz.getTypeParameters();
for (int index = 0; index < typeVariables.length; index++) {
TypeVariable<?> typeVariable = typeVariables[index];
String name = ReflectionUtils.getTypeVariableName(typeVariable);
Type nestType = types[index];
typeVariableCache.put(name, nestType);
if (supperClazz == clazz) {
init(nestType);
}
}
supperClazz = supperClazz.getSuperclass();
}
return this;
}
BaseMocker和ArrayMocker获取name修改如下
public static String getTypeVariableName(TypeVariable<?> typeVariable) {
GenericDeclaration declaration = typeVariable.getGenericDeclaration();
if (!(declaration instanceof Class<?>)) {
throw new MockException("unknown error");
}
return String.format("%s.%s", ((Class<?>) declaration).getName(), typeVariable.getName());
}
public static boolean isSystemClass(String name) {
return name.startsWith("java.") || name.startsWith("javax.");
}
Junit
@Test
public void testNestedGeneric() {
OuterBean<ArrayBean<BasicBean>> outerBean = JMockData.mock(new TypeReference<OuterBean<ArrayBean<BasicBean>>>() {
});
System.out.println(JSON.toJSONString(outerBean, true));
assertNotNull(outerBean);
}
@Test
public void testArrayGeneric() {
ArrayBean<String> outerBean = JMockData.mock(new TypeReference<ArrayBean<String>>() {
});
System.out.println(JSON.toJSONString(outerBean, true));
assertNotNull(outerBean);
}
有些有些场景需要指定的个数的list
我看模拟范围设置都是在config来设置
MockConfig mockConfig = new MockConfig()
.byteRange((byte) 0, Byte.MAX_VALUE)
.shortRange((short) 0, Short.MAX_VALUE)
.intRange(0, Integer.MAX_VALUE)
.floatRange(0.0f, Float.MAX_EXPONENT)
.doubleRange(0.0, Double.MAX_VALUE)
.longRange(0, Long.MAX_VALUE)
.dateRange("2010-01-01", "2020-12-30")
.sizeRange(5, 10)
.stringSeed("a", "b", "c")
.charSeed((char) 97, (char) 98);
这样的话是全局都享受这个配置。
但是我想某个class单独设定范围,比如user这个class里的int是1到5;school这个class里的int是10到20。
mockConfig.intRange(1, 5, User.class);
mockConfig.intRange(10, 20, School.class);
甚至可以精确到属性:
mockConfig.intRange(1, 5, User.class, "age");
mockConfig.intRange(10, 20, School.class, "createYear");
建议后续版本升级能够加上这个特性。
JMockData.mockCollection(new TypeReference<List>() {})。可能会构造出一个空的List
com.github.jsonzou.jmockdata.mocker.MapMocker#mock
line:25 ,存在java.lang.ArrayIndexOutOfBoundsException: 异常。
bug 复现:
@test
public void testMockData (){
//当 mock Map 类型时 不指定 泛型类型 ,会出现 数组下标越界问题
Map mock = JMockData.mock(Map.class);
System.out.println(JSON.toJSONString(mock));
}
如题,比如:
public class A{
B b;
public class B{
}
}
这时候this.clazz.newInstance()这种实例化方式会出错
目前通过默认无参构造方法,支持可选的构造方法。
getDataConfig(***,fieldName)
获取到字段
** 相关建议:
进入,只有源码,对于非maven项目的代码来说需要手动下载源码打包成jar包,有点麻烦,建议直接在release界面同时提供jar包和src压缩包
现在lombok框架使用挺广泛的, 希望支持一下.
如果存在某个对象,没有成员变量,对这个对象进行Mock的时候会抛数组越界
public class A {
private int a;
private String s;
private Date d;
//getter setter
}
public class B extent A {
private int b;
private String c;
//getter setter
}
public class BDataWrapper extends JmockDataWrapper {
private B b;
//getter setter
public static void main(String[] args) {
BDataWrapper b = JMockData.mock(BDataWrapper.class);
System.out.println(JSON.toJSONString(b.getB()));
//结果: {"a":0,"b":20,"c":"X L q h q S h p "}
}
}
缺少了继承来的s
和d
属性
泛型多层嵌套bug
对象中如果有枚举类,怎么破?
继承自泛型父类的Bean的Mock过程抛出null异常
RealData createMock = JMockData.mock(RealData.class);
/**
* 父类,省略get/set方法
* @param <T>
* @param <D>
*/
public static class BaseData<T,D>{
private T time;
private D data;
}
/**
* 子类
*/
public static class RealData extends BaseData<Date,String>{
}
How to set uuid field?
如果类的无参构造函数被私有化,会报异常
如果类中有final定义的常量也会有异常
Timestamp数据类型不支持?
#2
解决问题:mock子类时缺失继承来的属性
如果目标类型中包含final字段,会导致mock失败。
Enum[] enums = mockConfig.getcacheEnum(clazz.getName());
if (enums == null) {
try {
Field field = clazz.getDeclaredField("$VALUES");
field.setAccessible(true);
enums = (Enum[]) field.get(clazz);
if (enums.length == 0) {
throw new MockException("空的enum不能模拟");
}
mockConfig.cacheEnum(clazz.getName(), enums);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new MockException(e);
}
}
return (T) enums[RandomUtils.nextInt(0, enums.length)];
}
As the title, can provide the config to ignore some fields ?
1.反射效率低
2.尽量准守javaBean规范
3.即使用了反射,默认排查static final 字段
在很多时候,我们不希望mock静态字段的值,因此,建议增加对static字段mock的相关配置项
这个工具确实挺方便的 但是最新版本好像没支持LocalDate和LocalDateTime的模拟?
配合lombok
的@Accessors(chain = true)
使用,链式setter在开发中还是很常见的
例如
import lombok.*;
@Data
@Accessors(chain = true)
public class User {
private String name;
private String email;
private String phone;
public static void main(String[] args) {
User user = new User()
.setName("aaa")
.setEmail("[email protected]")
.setPhone("123456789");
}
}
但是我发现这种模式在jmockdata
中并不支持
看一下一下源码,做了一些改进,增加了对链式setter的支持
希望作者采纳
public static Map<Field, Method> fieldAndSetterMethod(Class clazz) throws IntrospectionException {
Map<Field, Method> map = new LinkedHashMap<>();
BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (Field field : clazz.getDeclaredFields()) {
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (!propertyDescriptor.getName().equals(field.getName())) {
continue;
}
if (propertyDescriptor.getWriteMethod() != null) {
map.put(field, propertyDescriptor.getWriteMethod());
break;
}
//方法名 属性名转换首字母大写
String setterName = "set" + StrUtil.upperFirst(propertyDescriptor.getName());
//根据方法名和参数类型,获取Method
Method setterMethod = ReflectUtil.getMethod(clazz, setterName, propertyDescriptor.getPropertyType());
if (setterMethod != null&& setterMethod.getReturnType().isAssignableFrom(clazz)) {
map.put(field, setterMethod);
break;
}
}
}
return map;
}
其中StrUtil.upperFirst()
和ReflectUtil.getMethod()
可以自己实现,我使用的是Hutool
里面的工具类
比如
Animal,Cat implements Animal, Dog implements Animal ...
有时候做测试会用到这种 bean,经常需要自己实现。如果加到 jmockdata 里,帮助会很大。
谢谢!
Caused by: com.github.jsonzou.jmockdata.MockException: com.github.jsonzou.jmockdata.MockException: java.lang.InstantiationException: java.sql.Timestamp
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:63)
at com.github.jsonzou.jmockdata.mocker.ClassMocker.mock(ClassMocker.java:38)
at com.github.jsonzou.jmockdata.mocker.BaseMocker.mock(BaseMocker.java:35)
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:57)
... 130 common frames omitted
Caused by: com.github.jsonzou.jmockdata.MockException: java.lang.InstantiationException: java.sql.Timestamp
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:63)
at com.github.jsonzou.jmockdata.mocker.ClassMocker.mock(ClassMocker.java:38)
at com.github.jsonzou.jmockdata.mocker.BaseMocker.mock(BaseMocker.java:35)
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:57)
... 133 common frames omitted
Caused by: java.lang.InstantiationException: java.sql.Timestamp
at java.lang.Class.newInstance(Class.java:427)
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:35)
... 136 common frames omitted
Caused by: java.lang.NoSuchMethodException: java.sql.Timestamp.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 137 common frames omitted
我的有些DTO的变量是public,并且没有get set的,mock出来的数据都是null
public class TestDto {
public String id;
public String name;
}
建议支持JDK8的时间类型如LocalDateTime,LocalDate,LocalTime等类型
Caused by: com.github.jsonzou.jmockdata.MockException: java.lang.InstantiationException: java.sql.Timestamp
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:43)
at com.github.jsonzou.jmockdata.mocker.ClassMocker.mock(ClassMocker.java:36)
at com.github.jsonzou.jmockdata.mocker.BaseMocker.mock(BaseMocker.java:35)
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:37)
... 41 more
如果一个类有一个类型为自身的字段,则mock这个对象的时候时会进入死循环。
public class CircularDependencyMockTest {
public static void main(String[] args) {
CircularDependencyObj obj = JMockData.mock(CircularDependencyObj.class);
System.out.println(obj);
}
public static class CircularDependencyObj {
@Getter
@Setter
private String field;
@Getter
@Setter
private CircularDependencyObj obj;
}
}
如果模拟bean时可以通过注解限定范围就好 ,通过注解的方式可以大大简少代码的编写
public class TypeReference<T> {
private Type type;
public TypeReference() {
Type superClass = this.getClass().getGenericSuperclass();
//做了一点注释
if (!(superClass instanceof Class)) {
this.type = ((ParameterizedType)superClass).getActualTypeArguments()[0];
}
}
public Type getType() {
return this.type;
}
//新增
public void setType(Type type) {
this.type = type;
}
}
使用场景:需要传入的Type不明确。只能运行时获取
例子如下,
public class TestSpring {
public static void main(String[] args) {
TestSpring testSpring = new TestSpring();
Method[] declaredMethods = testSpring.getClass().getDeclaredMethods();
DefaultParameterNameDiscoverer defaultParameterNameDiscoverer = new DefaultParameterNameDiscoverer();
for (Method declaredMethod : declaredMethods) {
if (Modifier.isStatic(declaredMethod.getModifiers())) {
continue;
}
String[] parameterNames = defaultParameterNameDiscoverer.getParameterNames(declaredMethod);
Type[] genericParameterTypes = declaredMethod.getGenericParameterTypes();
JSONObject jsonObject = new JSONObject();
for (int i = 0; i < genericParameterTypes.length; i++) {
Type genericParameterType = genericParameterTypes[i];
Object mock;
if (genericParameterType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
TypeReference typeReference = new TypeReference();
typeReference.setType(parameterizedType);
mock = Mock.mock(typeReference);
} else {
Class<?> clazz = (Class<?>) genericParameterType;
mock = Mock.mock(clazz);
}
jsonObject.put(parameterNames[i], mock);
}
System.out.println(jsonObject.toJSONString());
}
}
public void hello(String name, Date date, User user, List<User> userList, Map<String, User> userMap) {
}
}
1.过滤掉static/final修复的字段。如$jacocoData,serialVersionUID.
2.添加扩展点,方便使用者扩展
Caused by: java.lang.IllegalAccessException: Can not set static final long field com.aaa.serialVersionUID to java.lang.Long
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:80)
at sun.reflect.UnsafeQualifiedStaticLongFieldAccessorImpl.set(UnsafeQualifiedStaticLongFieldAccessorImpl.java:77)
at java.lang.reflect.Field.set(Field.java:764)
at com.github.jsonzou.jmockdata.util.ReflectionUtils.setFieldValue(ReflectionUtils.java:42)
at com.github.jsonzou.jmockdata.mocker.BeanMocker.setFieldValueByFieldAccessible(BeanMocker.java:67)
at com.github.jsonzou.jmockdata.mocker.BeanMocker.mock(BeanMocker.java:41)
... 5 more
未搜索到有效的联系方式,特提ISSUE,对此项目有兴趣,有意参加项目.
现为mybatis-plus成员,QQ332309254.
实体bean里添加LocalDate和LocalDateTime属性,生成mock报错:java.lang.InstantiationException
具体在BeanMocker里第30行
Object result = clazz.newInstance();
LocalDate是无法newInstance的
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.