Anybody have any good examples of using the String...
# kotlintest
q
Anybody have any good examples of using the StringSpec with listeners? First dip into kotlin in a while and I'm trying to start with unit testing.
m
you’re lucky: it was discussed just above 😉 https://kotlinlang.slack.com/archives/C18FWPKKL/p1575815899174100
l
Copy code
class MyTest : StringSpec() {
    override fun listeners() = listOf(myListener)

   init {
      "My First Test" {
      }
      "My Second Test" {
      }
   }
}
q
I ran into the same problem as he did with not being able to instantiate a variable before the tests were run. I was trying to convert this over to the kotlin test StringSpec syntax.
Copy code
abstract class BaseCacheTest {
	protected lateinit var cache: Cache

	@Before
	fun setup() {
		for (i in 0..99) {
			cache[i] = i
		}
	}

	@After
	fun tearDown() = cache.clear()

	@Test
	fun shouldClearAllEntries() {
		Assert.assertTrue(cache.size > 0)

		cache.clear()

		Assert.assertTrue(cache.size == 0)
	}

	@Test
	open fun shouldRemoveEntry() {
		Assert.assertNotNull(cache[1])

		cache.remove(1)

		Assert.assertNull(cache[1])
	}
l
You're inheriting BaseCacheTest in your tests?
q
No I didn't try that. I was trying to write using the StringSpec in lambda form and the programming style is different enough from OOP junit that I was struggling. I'll give that a try when I get home.
l
No, I mean, your test is an abstract class
Your JUnit test
You want to convert that to exactly one test?
q
No, sorry for the lousy explanation. This code comes from this study, https://github.com/kezhenxu94/cache-lite implemented in kotlin on caching. I was actually trying to physically rewrite the code base to gain an understanding of caching and kotlin.
l
Ok, so for your exact scenario, you probably want something like this:
Copy code
class CacheTest : StringSpec() {

private lateinit var cache: Cache

override fun beforeTest(testCase: TestCase) {
    for(i in 0..99)
        cache[i] = i
}

override fun afterTest(testCase: TestCase, result: TestResult) {
    cache.clear()
}

init {
    "Should clear all entries" {
        cache.size shouldBeGreaterThan 0
        cache.clear()
        cache.size shouldBe 0
    }

    "Should remove entry" {
        cache[1] shouldNotBe null
        cache.remove(1)
        cache[1] shouldBe null
    }
}

}
That would be the exact transition to StringSpec
q
I see. I was trying to inherit from both StringSpec and TestListener and that was becoming very complicated. This is much simpler.
l
StringSpec is a TestListener
q
Ahhhh
l
With a TestListener you can do some more advanced stuff, for example sharing listeners between tests
Think of a TestListener as a powerful JUnit Rule
☝️ 1
q
Ok, that makes sense, I was creating a second listener object and trying to register that in my string spec like in the documentation. https://github.com/kotlintest/kotlintest/blob/master/doc/reference.md#listeners This was leading to my cache not being initialized. Thanks for your help, I'm going to continue working on rewriting this tonight.
It's actually mentioned right there in the documentation. I missed that completely
Copy code
It's also important to notice that every Spec is also a TestListener, therefore you may override these functions directly in Spec.
l
xD
Take a look at the default listeners and extensions: https://github.com/kotlintest/kotlintest/blob/master/doc/extensions.md
You can see some use cases for when to use listeners there
q
Thanks, I've got some work to do. I'm hoping to do many of the build-your-own-x examples in kotlin. I want to start with a strong testing mental structure.
121 Views