{"id":26062100,"url":"https://github.com/thorbenkuck/mockk-method-probing","last_synced_at":"2026-04-21T06:33:47.896Z","repository":{"id":144576570,"uuid":"384691117","full_name":"ThorbenKuck/MockK-Method-Probing","owner":"ThorbenKuck","description":"Enhancing mockk and make testing asynchronous code easy.","archived":false,"fork":false,"pushed_at":"2021-07-17T12:46:50.000Z","size":59,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-08T15:50:29.664Z","etag":null,"topics":["java","kotlin","mockk","testing"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThorbenKuck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-10T12:19:28.000Z","updated_at":"2021-07-17T12:46:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ThorbenKuck/MockK-Method-Probing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ThorbenKuck/MockK-Method-Probing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThorbenKuck%2FMockK-Method-Probing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThorbenKuck%2FMockK-Method-Probing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThorbenKuck%2FMockK-Method-Probing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThorbenKuck%2FMockK-Method-Probing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThorbenKuck","download_url":"https://codeload.github.com/ThorbenKuck/MockK-Method-Probing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThorbenKuck%2FMockK-Method-Probing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32080426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T06:27:27.065Z","status":"ssl_error","status_checked_at":"2026-04-21T06:27:21.250Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","kotlin","mockk","testing"],"created_at":"2025-03-08T15:49:39.494Z","updated_at":"2026-04-21T06:33:47.891Z","avatar_url":"https://github.com/ThorbenKuck.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MockK Method Probing\n\n\u003e Testing asynchronous methods using modern and performant means\n\n[![Build Status](https://travis-ci.org/ThorbenKuck/MockK-Method-Probing.svg?branch=master)](https://travis-ci.org/ThorbenKuck/MockK-Method-Probing)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.thorbenkuck/MockK-Method-Probing/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.thorbenkuck/MockK-Method-Probing)\n\nMockk provides a lot of functions for mocking and spying, even integration in Spring and stuff. The only thing really missing is a way to test asynchronous code, or probing of methods in general.\n\nThis library is a small extension that enables tests to do just that, without massive overhead or busy/active waiting.\n\n## Motivation\n\nThis small library enables you to test asynchronous code (or synchronous code for that matter), without the need for busy or active waiting. It instead focuses on letting the test thread sleep until either the max wait time has elapsed, or the probed method was called.\n\nWith this library you can test asynchronous code more reliable and with better performance and without higher technical complexity in your tests.\n\nA more detailed motivation as to why one would use this library and where the idea for this library stems from can be found [here](MOTIVATION.md).\n\n## Getting started:\n\nAdd the following dependency to your build automation tool:\n\n### Maven:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.thorbenkuck\u003c/groupId\u003e\n    \u003cartifactId\u003emockk-method-probe\u003c/artifactId\u003e\n    \u003cversion\u003e0.1.1\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle:\n\n```groovy\ntestImplementation 'com.github.thorbenkuck:mockk-method-probe:0.1.1'\n```\n\n# Using the library\n\n\u003e Note: Even though most of the library is working best with spy classes, later down below there is an explanation for using custom mocks\n\nLet us imagine we have the following class, which is called asynchronously in our test:\n\n```kotlin\n\nclass ToTest {\n    fun testMethod(any: Any?): Any? {\n        return any\n    }\n    \n    fun triggerError() {\n        throw IllegalStateException()\n    }\n}\n```\n\n## MethodBarriers\n\nBarriers are a way of waiting for methods to being called and finish.\nThey are simpler, more light weight and faster than probes, though provide a lower total amount of transported information.\n\nThey allow analyzing execution exceptions, which is not true for all probe operations, since they require the method to return something.\n\nIf you want to continue your test once a method has been called, you can utilize the barrier like this:\n\n```kotlin\n// Arrange\nval toTest = spyk(ToTest())\nval barrier = barrier { toTest.testMethod(any()) }\n\n// Act\n// Trigger the test\n\n// Assert\nbarrier.tryToTraverse()\n```\n\nIf the method is not called within 10 seconds or an exception is raised while executing the stub, the test will fail. Otherwise, the test will simply continue.\n\nTo also continue the test, even if an exception is thrown, you can pass the argument `failOnException` to the method tryToTraverse and continue your test. For example like this:\n\n```kotlin\nval toTest = spyk(ToTest())\nval barrier = barrier { toTest.triggerError() }\n\n// Act\nthread {\n    toTest.triggerError()\n}\n\n// Assert\nbarrier.tryToTraverse(\n    failOnException = false\n)\nassertThat(barrier.raisedException()).isNotNull.isInstanceOf(IllegalStateException::class.java)\n```\n\nThis check can also be performed reactive, like this:\n\n```kotlin\nval barrier = barrier { toTest.triggerError() }\nbarrier.onError {\n    assertThat(it).isInstanceOf(IllegalStateException::class.java)\n}\n```\n\n\u003e Note: The onError will be called on the test thread, to not interact with the tested code.\n\n### MethodBarriers with \"strict\" mocks\n\nThe previous examples require the tested class to either be a relaxed mock, or a spy. If you want to use a \"normal\" mock, you can use the `barrierFor` method instead:\n\n```kotlin\n// Arrange\nval toTest = mockk\u003cToTest\u003e()\nval input = \"Foo\"\nval methodProbe = barrierFor { toTest.testMethod(any()) } returns \"Bar\"\n\n// Act\nvar result: Any? = null\nthread {\n    result = toTest.testMethod(input) // Ugly way of verifying that the answer is as mocked\n}\n\n// Assert\nmethodProbe.tryToTraverse() // Method has been called\nassertThat(result).isNotNull\n    .isEqualTo(\"Bar\")\n    .isNotEqualTo(input)\n```\n\nUsing `probing` instead of `probe` will return a custom version of the `MockKStubScope` called `ProbeMockKStubScope`. So you can use the normal mockk toolset and receive a MethodProbe to analyze the results.\n\n\n## MethodProbes\n\nIf you need more detailed information about the method (like return values or argument), you can utilize the method probe.\n\nOther than the MethodBarrier, a MethodProbe holds more relevant information than. This introduces a little more computational complexity and operational overhead, but if you need more information you can use this function\n\n```kotlin\n// Arrange\nval toTest = spyk(ToTest())\nval methodProbe = probe { toTest.testMethod(any()) }\n\n// Act\nthread {\n    toTest.testMethod(\"Foo\")\n}\n\n// Assert\nval firstArgument: String = methodProbe.getArgument(0)\nval result = methodProbe.getResult()\nassertThat(firstArgument).isEqualTo(result)\n```\n\nCalling any method on the method probe will wait until the respective information is present, meaning every method also allows you to define how long it will wait.\n\nSo, calling `methodProbe.getArgument(0)` waits until the spied method has been called, but not necessarily until it is finished.    \nIf the method is not called in the defined timeout (default 10 seconds), the test will fail\n\nCalling `methodProbe.getResult()` on the other hand waits until the spied method finishes, which implies that no exception is raised while doing so.    \nIf the method is not called or did not finish in the defined timeout (default 10 seconds), the test will fail.    \nThe same is true, if the spied upon code throws any exception.\n\n### MethodProbes with \"strict\" mocks\n\nThe previous examples require the tested class to either be a relaxed mock, or a spy. If you want to use a \"normal\" mock, you can use probing instead:\n\n```kotlin\n// Arrange\nval toTest = mockk\u003cToTest\u003e()\nval input = \"Foo\"\nval methodProbe = probing { toTest.testMethod(any()) } returns \"Bar\"\n\n// Act\nthread {\n    toTest.testMethod(input)\n}\n\n// Assert\nval probedResult = methodProbe.getResult()\nassertThat(result).isEqualTo(probedResult)\n    .isEqualTo(\"Bar\")\n    .isNotEqualTo(input)\n```\n\nUsing `probing` instead of `probe` will return a custom version of the `MockKStubScope` called `ProbeMockKStubScope`. So you can use the normal mockk toolset and receive a MethodProbe to analyze the results.\n\n### MethodProbes fluent asserts\n\nWhen you are using MethodProbes, you can utilize AssertJ, to validate your result. For example like this:\n\n\n```kotlin\n\n import java.util.concurrent.TimeUnit// Arrange\nval toTest = mockk\u003cToTest\u003e()\nval methodProbe = probe { toTest.testMethod(any()) }\n\n// Act\n// perform the test\n\n// Assert\nmethodProbe.assertThatResult()\n    .isNotNull\nmethodProbe.assertThatExecutionTimeMillis()\n    .isLessThen(TimeUnit.SECONDS.toMillis(1))\nmethodProbe.asserThatArguments()\n    .hasSize(1)\n```\n\n# Spring Test Support\n\nIf you are using Spring and are writing integration tests utilizing mockk [(also using springmockk)](https://github.com/Ninja-Squad/springmockk), you can utilize this library to write more reliable and performant integration tests, for example like this.\n\nLet's assume you want to test a create/update workflow, through Kafka and test that the result is correct. It can be done like this:\n\n```kotlin\n@SpringIntegrationTest // Setup Database, ApplicationContext, Kafka, whatever your heart desires\nclass ExampleIntegrationTest {\n    @SpyKBean\n    lateinit var kafkaListener: KafkaListener\n    \n    @Autowired\n    lateinit var entityRepository: EntityRepository\n    \n    @Test\n    fun validateCreateUpdate() {\n        // Arrange\n        val createMessage = CreateSomethingMessage(/* data */)\n        val updateMessage = UpdateSomethingMessage(/* data */)\n        val kafkaBarrier = barrier { kafkaConsumer.consume(any()) }\n\n        // Act\n        kafkaTemplate.sendDefault(createMessage).get()\n        kafkaTemplate.sendDefault(updateMessage).get()\n\n        // Assert \n        kafkaBarrier.tryToTraverse()\n\n        assertThat(entityRepository.findById(/* id */).get().version)\n            .withFailMessage(\"Entity was not updated\")\n            .isEqualTo(2)\n    }\n}\n```\n\nand you can insert as many probes, barriers and mocks as you want to:\n\n```kotlin\n@SpringIntegrationTest // Setup Database, ApplicationContext, Kafka, whatever your heart desires\nclass ExampleIntegrationTest {\n    @SpyKBean\n    lateinit var kafkaListener: KafkaListener\n    \n    @SpyKBean\n    lateinit var entityService: EntityService\n    \n    @Test\n    fun validateCreateUpdate() {\n        // Arrange\n        val createMessage = CreateSomethingMessage(/* data */)\n        val updateMessage = UpdateSomethingMessage(/* data */)\n        val kafkaBarrier = barrier { kafkaConsumer.consume(any()) }\n        val serviceProbe = probe { entityService.handle(ofType\u003cUpdateSomethingMessage\u003e()) }\n\n        // Act\n        kafkaTemplate.sendDefault(createMessage).get()\n        kafkaTemplate.sendDefault(updateMessage).get()\n\n        // Assert\n        kafkaBarrier.tryToTraverse()\n        val entity = serviceProbe.getResult()\n\n        assertThat(entity.version)\n            .withFailMessage(\"Entity was not updated\")\n            .isEqualTo(2)\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthorbenkuck%2Fmockk-method-probing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthorbenkuck%2Fmockk-method-probing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthorbenkuck%2Fmockk-method-probing/lists"}