Method Barriers Basics - ThorbenKuck/MockK-Method-Probing GitHub Wiki
A MethodBarrier is a barrier, that blocks a Thread until another method has been called.
Principal
A barrier is simple. It bridges a potential asynchronous method to the test. All errors are transcribed from the method to the test, failing the test if any error happens in the code that should be executed. The barrier allows to detect methods call without relying on spin locks or busy waiting, making it thread safe and business safe.
Using a barrier
For tests, let's assume that we want to wait with a test until ExampleService#finish
has been called with an id as a parameter.
For utilising this library, we need a spy or a mock to wrap our barrier around.
val service = ExampleService()
val serviceSpy = spyk(service)
Now, with this serviceSpy, we can create a barrier like this:
import de.thorbenkuck.mockk.barrier
val methodBarrier = barrier { serviceSpy.finish(any()) }
A method stub right here, will follow the same rules, as if we where to call every
in mockk. Only if the correct match is called, the barrier will be released.
This barrier can then be tried to traverse by calling it like this:
methodBarrier.tryToTraverse()
How does this interfere with testing?
This method call methodBarrier.tryToTraverse()
will block the testing thread, until the method serviceSpy.finish
has been invoked and finished. There are certain thinks to keep in mind:
- If the method
serviceSpy.finish
is not finished within 10 seconds after themethodBarrier.tryToTraverse
has been called, the test fails - If the method
serviceSpy.finish
throws an exception, the test fails
Those parameters can be tweaked, which is explained in the next articles.
Spring and SpringMockK
Interoparability withIf you want to test something and are running spring, you can do something like this:
class TestClass {
@SpyKBean
private lateinit var service: ExampleService
@Test
fun test() {
// Arrange
val barrier = barrier { service.finish(any()) }
// Act
// Start the async, for example using Kafka
// Assert
barrier.tryToTraverse()
}
}
This makes it small, easy and quick to use