jmockdata icon indicating copy to clipboard operation
jmockdata copied to clipboard

kotlin data class 不支持mock

Open gcdd1993 opened this issue 3 years ago • 0 comments

在使用kotlin时,遇到了一些问题

场景

User类

data class Person(var name: String, var age: Int)

mock 方法

val mock = JMockData.mock(Person::class.java)
println("mock data: $mock")

1.NoArg

找不到无参构造器,kotlin的data class默认没有无参构造器

java.lang.NoSuchMethodException:JmockdataTest$Person.<init>()

使用org.jetbrains.kotlin.plugin.noarg的Gradle plugin即可

@NoArg
data class Person(var name: String, var age: Int)

2.mock出来的数据没有填充值

mock data: Person(name=null, age=0)

debug后发现 BeanMocker#isSupportMock

private boolean isSupportMock(Class<?>clazz){
  boolean unSupport = clazz == Object.class
          || clazz.isInterface()
          || clazz.isEnum()
          || clazz.isAnnotation()
          || Modifier.isAbstract(clazz.getModifiers())
          || Modifier.isProtected(clazz.getModifiers())
          || Modifier.isPrivate(clazz.getModifiers())
          || Modifier.isInterface(clazz.getModifiers())
          || Modifier.isTransient(clazz.getModifiers())
          || Modifier.isFinal(clazz.getModifiers())
          || Modifier.isNative(clazz.getModifiers())
          || Modifier.isFinal(clazz.getModifiers());

  return !unSupport;

有两行isFinal的判断,由于kotlin默认都是Final,所以这里执行后是unSupport

改为open

@NoArg
open class Person(var name: String, var age: Int) {
    override fun toString(): String {
        return "Person(name=$name, age=$age)"
    }
}

执行mock

mock data: Person(name=bXMUfELM, age=8171)

虽然解决了,但是我有一些问题想请教作者

为何要进行isFinal的判断?

在项目内并没有发现有用到继承或者cglib生成代码的部分,使用的是反射进行赋值,不知道是否愚见,希望作者解答

gcdd1993 avatar Jun 22 '21 05:06 gcdd1993