2

I wrote the following test:

@RunWith(SpringJUnit4ClassRunner::class)
class KotlinTest : BehaviorSpec() {
    init {
        given("a stack") {
            val stack = Stack<String>()
            `when`("an item is pushed") {
                stack.push("kotlin")
                then("the stack should not be empty") {
                    stack.isEmpty() shouldBe true
                }
            }
            `when`("the stack is popped") {
                stack.pop()
                then("it should be empty") {
                    stack.isEmpty() shouldBe false
                }
            }
        }
    }
}

When I try to run it, I have the following error:

java.lang.Exception: No runnable methods

at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:138)

I know that the problem is that I am trying to run a test written with KotlinTest with Spring, but how can I do it? What runner should I use?

The example test doesn't need spring, this was just a simple example that I wrote to isolate the problem

jonathanrz
  • 4,206
  • 6
  • 35
  • 58

3 Answers3

1

You wrote your test in the constructor. Tests should be written in functions with @Test annotation. Your code is more less the equivalent of:

@RunWith(SpringJUnit4ClassRunner.class)
public final class JavaTest extends BehaviorSpec {

    public JavaTest() {
         // given stack, when item is pushed, ...
    }
}

What you want instead is

@RunWith(SpringJUnit4ClassRunner.class)
public final class JavaTest extends BehaviorSpec {

    @Test
    public void testName() {
        // given stack, when item is pushed, ...
    }
}

To achieve this you need to use fun keyword to define a function. The result should look more less like this:

@RunWith(SpringJUnit4ClassRunner::class)
class KotlinTest : BehaviorSpec() {

    @Test fun testName() {
        given stack, when item is pushed, ...
    }
}
Mibac
  • 8,990
  • 5
  • 33
  • 57
0

You've specified @RunWith(SpringJUnit4ClassRunner::class). That's overriding the KotlinTest runner, which is KTestJUnitRunner. In order for your KotlinTest tests to be picked up, you need to use the correct test runner.

Removing your RunWith annotation should fix the problem. Then the test runner will be inherited from the BehaviorSpec superclass as intended.

Sam
  • 8,330
  • 2
  • 26
  • 51
  • 1
    If I use KTestJUnitRunner, spring don't inject my dependencies. – jonathanrz Jun 30 '17 at 21:52
  • You can use `@SpringClassRule` and `@SpringMethodRule` to enable the spring test context features while not using the spring test runner. – Sam Jun 30 '17 at 21:54
  • the '@SpringMethodRule' can't be defined in the init method. I couldn't find the '@SpringClassRule' annotation. – jonathanrz Jun 30 '17 at 21:58
0

It seems to me that the logic of the test is the opposite it should be: first stack.isEmpty() shouldBe false second stack.isEmpty() shouldBe true When I run the test with gradle (and without @RunWith) with kotlintest I cannot fix the problem in any way: nosense java.util.EmptyStackException and java.lang.AssertionError

        When("an item is pushed") {
            stack.push("kotlin")
            Then("the stack should not be empty") { 
                  stack.isEmpty() shouldBe false
                //stack.empty() shouldBe false
                //stack.size shouldBe gt(0)

            }
        }
        When("the stack is popped") {
            stack.pop()
            Then("it should be empty") {
                stack.isEmpty() shouldBe true        
            }
        }

I know this is not the question you ask, but your logic seems reversed. I cannot fix with gradle and kotlintest.

kgangadhar
  • 4,886
  • 5
  • 36
  • 54