Unable to Use JUnit Theories


#1

My functioning Java code:

@RunWith(Theories.class) public class TestDoubling {   @DataPoints   public static int[] values() {   return new int[] { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };   }

  @Theory
  public void testDoubling(Integer a) {
  assertThat(doubling(a), is(a * 2));
  }

  public int doubling(int value) { return value * 2; }
}


my (hopefully) equivalent kotlin code which fails:

RunWith(javaClass<Theories>()) class Testing {   class object {   DataPoints   fun values(): Array<Int> {            return array(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)   }   }

  Theory
  fun testDoubling(value: Integer) {
  assertThat(doubling(value.intValue()), is(value.intValue() * 2))
  }

  fun doubling(a: Int): Int = a * 2
}


Please note that the java.lang.Integer is required- a simple int will cause the following error:

java.lang.AssertionError: Never found parameters that satisfied method assumptions.  Violated assumptions: []   at org.junit.Assert.fail(Assert.java:88)   at org.junit.experimental.theories.Theories$TheoryAnchor.evaluate(Theories.java:100)

That is also the exact same error message I get for the Kotlin version, even though they are- at least to my noobish eye- identical. Changing the Array<Int> to an IntArray didn't work nor removing the class object.


#2

Currently you can not define a proper static method in Kotlin. We will add something to mitigate this problem in our Java interop layer. Thanks for the report.

BTW, have you tried Spek (http://blog.jetbrains.com/kotlin/2014/02/speka-specification-framework/)?


#3

Logged http://youtrack.jetbrains.com/issue/KT-4861


#4

You could directly annotate parameter:

RunWith(javaClass<Theories>())

class Testing {

  Theory

  fun testDoubling(TestedOn(ints = *intArray(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)) value: Int) {

  assertThat(doubling(value), `is`(value * 2))

  }

  fun doubling(a: Int): Int = a * 2

}

or move parameter supplier to separate class as described at https://github.com/junit-team/junit/wiki/Theories


#5

Now you can use platformStatic annotation on class object functions:

RunWith(javaClass<Theories>()) public class TestDoubling {   class object {            platformStatic DataPoints            public fun values(): IntArray {                    return intArray(-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)            }   }

   &nbsp;&nbsp;Theory
   &nbsp;&nbsp;public fun testDoubling(a: Int?) {

                  Assert.assertThat<Int>(doubling(a!!), is<Int>(a * 2))
  }

   &nbsp;&nbsp;public fun doubling(value: Int): Int {

                  return value * 2
  }
}


#6

This works for "bleeding edge" Kotlin, build 0.8.1162 and later