Тест Kotlin, как запустить BeforeEach с тестовым стилем DescribeSpec - PullRequest
2 голосов
/ 09 июня 2019

Я пытаюсь написать KotlinTest тесты, работающие на JUnit5, с Описать спецификацию стиля .

Когда мне нужно инициализировать одну и ту же переменную для некоторых тестов, @BeforeEach не работает внутри DescribeSpec.

Как можно инициализировать данные перед каждым тестом?

class BlockchainUT : DescribeSpec({

    var blockchain = Blockchain()

    @BeforeEach
    fun beforeEach() {
        blockchain = Blockchain()
        blockchain.addBlock(listOf("foo1", "bar1"))
        blockchain.addBlock(listOf("foo2", "bar2"))
        blockchain.addBlock(listOf("foo3", "bar3"))
    }

    describe("isValidChain()") {

        context("when the chain does not start with the genesis block") {

            blockchain.chain[0] = Block(
                    System.currentTimeMillis(),
                    "---",
                    "xxx",
                    listOf("foo", "bar"))

            it("returns false") {
                Blockchain.isValid(blockchain) shouldBe false
            }
        }

        context("when the chain starts with the genesis block and has multiple blocks") {

            context("and a lastHash reference has changed returns false") {
                blockchain.chain[2] = Block(
                        blockchain.chain[2].timestamp,
                        "broken-lastHash",
                        blockchain.chain[2].hash,
                        blockchain.chain[2].data)
                it("returns false") {
                    Blockchain.isValid(blockchain) shouldBe false
                }
            }

            context("and the chain contains a block with an invalid field") {
                blockchain.chain[2] = Block(
                        blockchain.chain[2].timestamp,
                        blockchain.chain[2].lastHash,
                        blockchain.chain[2].hash,
                        listOf("some-bad-and-evil-data"))
                it("returns false") {
                    Blockchain.isValid(blockchain) shouldBe false
                }
            }
        }

    }
})

1 Ответ

2 голосов
/ 11 июня 2019

В новой версии KotlinTest 3.3 появились новые Слушатели для определения beforeTest, afterTest, beforeSpec и т. Д.

В этом случае возможное решение должноbe:

class BlockchainUT : DescribeSpec(), TestListener {

    var blockchain = Blockchain()

    override fun beforeTest(describe: TestCase): Unit {
        blockchain = Blockchain()
        blockchain.addBlock(listOf("foo1", "bar1"))
        blockchain.addBlock(listOf("foo2", "bar2"))
        blockchain.addBlock(listOf("foo3", "bar3"))
    }

    init {
        describe("isValidChain()") {

            context("when the chain starts with the genesis block and has multiple blocks") {

                context("and a lastHash reference has changed returns false") {

                    blockchain.chain[2] = Block(
                            blockchain.chain[2].timestamp,
                            "broken-lastHash",
                            blockchain.chain[2].hash,
                            blockchain.chain[2].data)

                    it("returns false") {
                        Blockchain.isValid(blockchain) shouldBe false
                    }
                }

                context("and the chain contains a block with an invalid field") {

                    blockchain.chain[2] = Block(
                            blockchain.chain[2].timestamp,
                            blockchain.chain[2].lastHash,
                            blockchain.chain[2].hash,
                            listOf("some-bad-and-evil-data"))

                    it("returns false") {
                        Blockchain.isValid(blockchain) shouldBe false
                    }
                }

                context("and the chain does not contain any invalid blocks") {

                    it("returns true") {
                        Blockchain.isValid(blockchain) shouldBe true
                    }
                }
            }
        }
    }
}

Также может быть решена с помощью новых Режимов изоляции , определяющих режим изоляции на InstancePerLeaf.От io.kotlintest.IsolationMode Javadoc:

A new instance of the [Spec] class is instantiated for every
[TestCase] - both containers and leaf tests - and they are
executed once the previous test has completed.
For example, in the following test plan:
"this test" {
  println("a")
  "nested test" {
    println("b")
  }
  "nested test 2" {
    println("c")
  }
}
The output will be:
a
a
b
a
c

И, наконец, переместите код, который вы хотите повторить для каждого [TestCase] ​​
class BlockchainUT : DescribeSpec(){

    override fun isolationMode() = IsolationMode.InstancePerTest

        describe("isValidChain()") {

            context("when the chain starts with the genesis block and has multiple blocks") {

                var blockchain = Blockchain()
                blockchain.addBlock(listOf("foo1", "bar1"))
                blockchain.addBlock(listOf("foo2", "bar2"))
                blockchain.addBlock(listOf("foo3", "bar3"))

                context("and a lastHash reference has changed returns false") {

                    blockchain.chain[2] = Block(
                            blockchain.chain[2].timestamp,
                            "broken-lastHash",
                            blockchain.chain[2].hash,
                            blockchain.chain[2].data)

                    it("returns false") {
                        Blockchain.isValid(blockchain) shouldBe false
                    }
                }

                context("and the chain contains a block with an invalid field") {

                    blockchain.chain[2] = Block(
                            blockchain.chain[2].timestamp,
                            blockchain.chain[2].lastHash,
                            blockchain.chain[2].hash,
                            listOf("some-bad-and-evil-data"))

                    it("returns false") {
                        Blockchain.isValid(blockchain) shouldBe false
                    }
                }

                context("and the chain does not contain any invalid blocks") {

                    it("returns true") {
                        Blockchain.isValid(blockchain) shouldBe true
                    }
                }
            }
        }
    }
}

...