首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用kotlin和jmockit

使用kotlin和jmockit
EN

Stack Overflow用户
提问于 2015-02-24 12:55:23
回答 2查看 1.8K关注 0票数 8

我需要一些建议用jmockit和kotlin。

(剪切)这是正在测试的我的(Java)类:

代码语言:javascript
复制
public final class NutritionalConsultant {
    public static boolean isLunchTime() {
        int hour = LocalDateTime.now().getHour();
        return hour >= 12 && hour <= 14;
    }
}

(j.1)这是一个实用的Java测试类

代码语言:javascript
复制
@RunWith(JMockit.class)
public class NutritionalConsultantTest {
    @Test
    public void shouldReturnTrueFor12h(@Mocked final LocalDateTime dateTime) {
        new Expectations() {{
            LocalDateTime.now(); result = dateTime;
            dateTime.getHour(); result = 12;
        }};
        boolean isLunchTime = NutritionalConsultant.isLunchTime();
        assertThat(isLunchTime, is(true));
    }
}

(kt.1)然而,相应的kotlin类抛出一个异常

代码语言:javascript
复制
RunWith(javaClass<JMockit>())
public class NutritionalConsultantKt1Test {

    Test
    public fun shouldReturnTrueFor12h(Mocked dateTime : LocalDateTime) {
        object : Expectations() {{
            LocalDateTime.now(); result = dateTime;
            dateTime.getHour(); result = 12;
        }}
        val isLunchTime = NutritionalConsultant.isLunchTime()
        assertThat(isLunchTime, eq(true));
    }
}

例外:

代码语言:javascript
复制
java.lang.Exception: Method shouldReturnTrueFor12h should have no parameters
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:41)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

与gradle一起运行时,也会引发相同的异常。

(kt.2)通过使用kotlin的@ syntax语法,我得到了一个不同的例外:

代码语言:javascript
复制
RunWith(javaClass<JMockit>())
public class NutritionalConsultantKt2Test {
    Mocked
    var dateTime : LocalDateTime by Delegates.notNull()

    Test
    public fun shouldReturnTrueFor12h() {
        object : Expectations() {{
            LocalDateTime.now(); result = dateTime;
            dateTime.getHour(); result = 12;
        }}
        val isLunchTime = NutritionalConsultant.isLunchTime()
        assertThat(isLunchTime, eq(true));
    }
}

例外:

代码语言:javascript
复制
java.lang.IllegalArgumentException: Final mock field "dateTime$delegate" must be of a class type
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

编辑20150224可能与“对于模拟字段而言,声明类型的实例将由JMockit自动创建并分配给该字段,条件是它不是最终的”。(来自http://jmockit.org/tutorial/BehaviorBasedTesting.html)

(kt.3)但是,将val更改为var并使用!操作员导致了一个工作测试..。但这不是惯用的kotlin代码:

代码语言:javascript
复制
RunWith(javaClass<JMockit>())
public class NutritionalConsultantKt3Test {
    Mocked
    var dateTime : LocalDateTime? = null

    Test
    public fun shouldReturnTrueFor12h() {
        object : Expectations() {{
            LocalDateTime.now(); result = dateTime;
            dateTime!!.getHour(); result = 12;
        }}
        val isLunchTime = NutritionalConsultant.isLunchTime()
        assertThat(isLunchTime, eq(true));
    }
}

你用kotlin和jmockit玩得更成功吗?

EN

回答 2

Stack Overflow用户

发布于 2015-02-24 15:34:55

我不认为您将能够使用来自Kotlin的JMockit (或者大多数其他JVM替代语言,可能是Groovy除外),无论如何也不能可靠地使用。

原因是: 1) JMockit的开发没有考虑到这些语言,也没有用它们进行测试;2)这些语言在编译为字节码时会产生额外的或不同的构造,可能会混淆像JMockit这样的工具;此外,它们通常会插入对自己内部API的调用,这也可能会阻碍它们的开发。

在实践中,替代语言倾向于开发自己的测试/模拟/等等工具,这些工具不仅对该语言及其运行时运行良好,而且还让您充分利用该语言的优势。

就我个人而言,即使我能认识到这些语言带来的许多好处(我特别喜欢Kotlin),我还是宁愿坚持使用Java ( Java继续发展--参见Java 8)。事实是,到目前为止,Java的广泛使用还没有替代的JVM语言,而且(IMO)它们永远也不会。

票数 3
EN

Stack Overflow用户

发布于 2015-02-26 17:42:55

我们做了一些实验,发现您可以定义如下特殊功能:

代码语言:javascript
复制
fun uninitialized<T>() = null as T

然后像这样使用它:

代码语言:javascript
复制
[Mocked] val dateTime : LocalDateTime = uninitialized()

您也可以使用它而不是Matchers.any()来达到同样的效果。我们将考虑将其添加到编译器或标准库中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28696399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档