junit – 使用kotlin和jmockit

前端之家收集整理的这篇文章主要介绍了junit – 使用kotlin和jmockit前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要一些使用jmockit和kotlin的建议.

(CUT)这是我测试的(Java)类:

  1. public final class NutritionalConsultant {
  2. public static boolean isLunchTime() {
  3. int hour = LocalDateTime.now().getHour();
  4. return hour >= 12 && hour <= 14;
  5. }
  6. }

(j.1)这是一个有效的Java测试类

  1. @RunWith(JMockit.class)
  2. public class NutritionalConsultantTest {
  3. @Test
  4. public void shouldReturnTrueFor12h(@Mocked final LocalDateTime dateTime) {
  5. new Expectations() {{
  6. LocalDateTime.now(); result = dateTime;
  7. dateTime.getHour(); result = 12;
  8. }};
  9. boolean isLunchTime = NutritionalConsultant.isLunchTime();
  10. assertThat(isLunchTime,is(true));
  11. }
  12. }

(kt.1)但是,相应的kotlin类会引发异常

  1. RunWith(javaClass<JMockit>())
  2. public class NutritionalConsultantKt1Test {
  3.  
  4. Test
  5. public fun shouldReturnTrueFor12h(Mocked dateTime : LocalDateTime) {
  6. object : Expectations() {{
  7. LocalDateTime.now(); result = dateTime;
  8. dateTime.getHour(); result = 12;
  9. }}
  10. val isLunchTime = NutritionalConsultant.isLunchTime()
  11. assertThat(isLunchTime,eq(true));
  12. }
  13. }

例外:

  1. java.lang.Exception: Method shouldReturnTrueFor12h should have no parameters
  2. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  3. at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
  4. at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:41)
  5. at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
  6. at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
  7. at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

使用gradle运行时会抛出相同的异常.

(kt.2)在kotlin中使用@Mocked语法我得到了一个不同的异常:

  1. RunWith(javaClass<JMockit>())
  2. public class NutritionalConsultantKt2Test {
  3. Mocked
  4. var dateTime : LocalDateTime by Delegates.notNull()
  5.  
  6. Test
  7. public fun shouldReturnTrueFor12h() {
  8. object : Expectations() {{
  9. LocalDateTime.now(); result = dateTime;
  10. dateTime.getHour(); result = 12;
  11. }}
  12. val isLunchTime = NutritionalConsultant.isLunchTime()
  13. assertThat(isLunchTime,eq(true));
  14. }
  15. }

例外:

  1. java.lang.IllegalArgumentException: Final mock field "dateTime$delegate" must be of a class type
  2. at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
  3. at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
  4. at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
  5. at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

编辑20150224这可能与“对于模拟字段有关,声明类型的实例将由JMockit自动创建并分配给字段,前提是它不是最终的.” (自http://jmockit.org/tutorial/BehaviorBasedTesting.html起)

(kt.3)然而,将val更改为var并使用!!运算符导致工作测试…但这不是惯用的kotlin代码

  1. RunWith(javaClass<JMockit>())
  2. public class NutritionalConsultantKt3Test {
  3. Mocked
  4. var dateTime : LocalDateTime? = null
  5.  
  6. Test
  7. public fun shouldReturnTrueFor12h() {
  8. object : Expectations() {{
  9. LocalDateTime.now(); result = dateTime;
  10. dateTime!!.getHour(); result = 12;
  11. }}
  12. val isLunchTime = NutritionalConsultant.isLunchTime()
  13. assertThat(isLunchTime,eq(true));
  14. }
  15. }

使用kotlin和jmockit有没有更多的成功?

解决方法

我不认为您能够使用Kotlin中的JMockit(或者大多数其他JVM替代语言,可能除了Groovy),无论如何都不可靠.

原因是1)JMockit并没有考虑到这些语言而开发,也没有用它们进行测试; 2)这些语言在编译成字节码时会产生额外的或不同的结构,这些结构可能会混淆像JMockit这样的工具;他们通常也会调用自己的内部API,这也可能会妨碍他们.

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

就个人而言,即使我能够认识到这些语言带来的诸多好处(我特别喜欢Kotlin),我宁愿坚持使用Java(它继续发展 – 参见Java 8).事实上,到目前为止,没有其他JVM语言可以接近Java的广泛使用,而且(IMO)它们永远不会.

猜你在找的Java相关文章