<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MockK Archives - Codersee blog- Kotlin on the backend</title>
	<atom:link href="https://blog.codersee.com/tag/mockk/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Kotlin &#38; Backend Tutorials - Learn Through Practice.</description>
	<lastBuildDate>Wed, 16 Apr 2025 04:49:36 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blog.codersee.com/wp-content/uploads/2025/04/cropped-codersee_logo_circle_2-32x32.png</url>
	<title>MockK Archives - Codersee blog- Kotlin on the backend</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>MockK with Coroutines [5/5]</title>
		<link>https://blog.codersee.com/mockk-coroutines/</link>
					<comments>https://blog.codersee.com/mockk-coroutines/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 04 Mar 2025 17:55:48 +0000</pubDate>
				<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[MockK]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=17512712</guid>

					<description><![CDATA[<p>In the last article in a series, we are going to learn everything we need to know to work with MockK and Kotlin coroutines. </p>
<p>The post <a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>At this point, we spent a lot of time exploring MockK features and syntax, so at this point, adding coroutines will be trivial, trust me😉</p>



<p>Of course, you can find the rest of the series on my blog, too:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li>MockK with Coroutines [5/5]</li>
</ul>



<h2 class="wp-block-heading" id="h-video-content">Video Content</h2>



<p>As always, if you prefer a video content, then please check out my latest YouTube video:</p>


<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><a href="https://blog.codersee.com/mockk-coroutines/"><img decoding="async" src="https://blog.codersee.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2FW0nnZl4R6C0%2Fhqdefault.jpg" alt="YouTube Video"></a><br /><br /><figcaption></figcaption></figure>


<h2 class="wp-block-heading" id="h-additional-imports">Additional Imports</h2>



<p>As the first step, let&#8217;s add the necessary import:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.1")</pre>



<p>This package provides utilities for testing coroutines.</p>



<p>And thanks to that, we can mock and test suspend functions.</p>



<h2 class="wp-block-heading">Code To Test</h2>



<p>Following, let&#8217;s introduce the suspended functions:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Eight(
    private val one: EightOne,
    private val two: EightTwo,
) {
    suspend fun funToTest(): String {
        return "${one.returnInt()} ${two.returnString()}"
    }
}

class EightOne {
    suspend fun returnInt(): Int = 10
}

class EightTwo {
    suspend fun returnString(): String = "Some String"
}</pre>



<p>And I know it does not make sense. But it is not important here😉</p>



<p>The important part is that we have suspended functions so we can start implementing tests.</p>



<h2 class="wp-block-heading">MockK with Coroutines</h2>



<p>As the next step, let&#8217;s try to implement the test &#8220;the old way&#8221;:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class EightTest {
    private val one: EightOne = mockk()
    private val two: EightTwo = mockk()

    private val eight = Eight(one, two)

    @Test
    fun `should return 1 codersee`() {
        every { one.returnInt() } returns 1
        every { two.returnString() } returns "codersee"

        val result = eight.funToTest()

        assertEquals("1 codersee", result)

        verifySequence {
            one.returnInt()
            two.returnString()
        }
    }
}</pre>



<p>As a result, we can see the compiler complaining about our suspended functions:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Suspend function 'returnInt' should be called only from a coroutine or another suspend function
Suspend function 'returnString' should be called only from a coroutine or another suspend function
Suspend function 'funToTest' should be called only from a coroutine or another suspend function</pre>



<p>So, as the first step, let&#8217;s add the <code>runTest</code> to get rid of the last error:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 1 codersee`() = runTest {</pre>



<p>The <code>runTest</code> is not related to the MockK itself. It comes from <code>kotlinx.coroutines</code> and executes our test body in a new coroutine, returning <code>TestResult</code> .</p>



<p>When it comes to MockK, then we can work with coroutines and suspended functions by simply adding the &#8220;co&#8221; suffix for all functions:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class EightTest {
    private val one: EightOne = mockk()
    private val two: EightTwo = mockk()

    private val eight = Eight(one, two)

    @Test
    fun `should return 1 codersee`() = runTest {
        coEvery { one.returnInt() } returns 1
        coEvery { two.returnString() } returns "codersee"

        val result = eight.funToTest()

        assertEquals("1 codersee", result)

        coVerifySequence {
            one.returnInt()
            two.returnString()
        }
    }
}</pre>



<p>And yes, this is that easy!😉</p>



<p>MockK comes with plenty of functions to work with suspend functions, like:</p>



<ul class="wp-block-list">
<li><code>coVerify</code></li>



<li><code>coEvery</code></li>



<li><code>coJustRun</code></li>



<li><code>coJustAwait</code></li>



<li><code>coAnswers</code></li>



<li>and many more😉</li>
</ul>



<h2 class="wp-block-heading">Issue With Spies</h2>



<p>Lastly, at the moment of writing, there is one issue with spies and coroutines in MockK. You can see all the details here: <a href="https://github.com/mockk/mockk/issues/554">https://github.com/mockk/mockk/issues/554</a></p>



<p>Assuming this is quite an old one, I wouldn&#8217;t expect it to be fixed in the near future.</p>



<p>But if that is the case, then please let me know in the comments below.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>That&#8217;s all for this series about MockK &#8211; the mocking library for Kotlin.</p>



<p>During our time together, we learned A LOT, and I believe you are ready to use it in your projects!</p>



<p>Let me know your thoughts in the comments below, and if you are looking for the other articles, then here you are:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li>MockK with Coroutines [5/5]</li>
</ul>
<p>The post <a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/mockk-coroutines/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MockK: Spy, Relaxed Mock, and Partial Mocking [4/5]</title>
		<link>https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/</link>
					<comments>https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 04 Mar 2025 17:55:42 +0000</pubDate>
				<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[MockK]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=17512701</guid>

					<description><![CDATA[<p>In the fourth artcile in a series, we are going to learn what are MockK spies, relaxed mocks and how to do a partial mocking.</p>
<p>The post <a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spy, Relaxed Mock, and Partial Mocking [4/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>At this point, we know quite a lot about mocks, verification, and how to perform stubbings. In this lesson, we are going to expand our horizons and see additional features useful in day-to-day scenarios, like relaxed mocks.</p>



<p>Of course, you can find the rest of the series on my blog, too:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li><a href="MockK: Objects, Top-Level, and Extension Functions [3/5]">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li>MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<h2 class="wp-block-heading" id="h-video-content">Video Content</h2>



<p>As always, if you prefer a video content, then please check out my latest YouTube video:</p>


<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/"><img decoding="async" src="https://blog.codersee.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2FyukKpPr_iBg%2Fhqdefault.jpg" alt="YouTube Video"></a><br /><br /><figcaption></figcaption></figure>


<h2 class="wp-block-heading" id="h-mockk-relaxed-mock">MockK: Relaxed Mock</h2>



<p>What does a <strong>relaxed mock</strong> mean?</p>



<p>Well, long story short, it is <strong>a mock that returns some value for all functions</strong>. In other words, the value is returned even if we do not provide a stubbing.</p>



<p>To better understand, let&#8217;s take a look at the example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Five(
    private val one: FiveOne,
) {
    fun funToTest(): String {
        one.returnInt()
        return one.returnString()
    }
}

class FiveOne {
    fun returnInt(): Int = 10
    fun returnString(): String = "Some String"
}</pre>



<p>As we can see, the function we want to test invokes two another: <code>returnInt</code> and <code>returnString</code>.</p>



<p>And I am pretty sure that at this point, you know the result without even running the test:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class FiveTest {

    private val one: FiveOne = mockk()
    private val five = Five(one)

    @Test
    fun `should return mocked string`() {
        every { one.returnString() } returns "mocked"

        val result = five.funToTest()

        assertEquals("mocked", result)
    }
}</pre>



<p>That&#8217;s right, it fails, and MockK complains about missing answer:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">no answer found for FiveOne(#1).returnInt() among the configured answers: (FiveOne(#1).returnString()))
io.mockk.MockKException: no answer found for FiveOne(#1).returnInt() among the configured answers: (FiveOne(#1).returnString()))</pre>



<p>And as you may have guessed, a relaxed mock may help us here a bit. But how do we define it in MockK?</p>



<p>It&#8217;s easy; the only thing we need is to set up the <code>relaxed</code> flag on creation:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private val one: FiveOne = mockk(relaxed = true)</pre>



<p>(When working with annotations, we can use <code>@RelaxedMockK</code> instead of <code>@MockK</code>)</p>



<p>So, now, when we repeat our test, <strong>it passes!</strong></p>



<p>Moreover, we could even completely skip the stubbing part:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return empty string`() {
    val result = five.funToTest()

    assertEquals("", result)
}</pre>



<p>But please don&#8217;t do that in your tests and treat them as a curiosity😉</p>



<p>And before we head to the next part, I just wanted to mention that <strong>for Unit-returning functions, we must set a separate flag- </strong><code><strong>relaxUnitFun</strong></code><strong> &#8211; to true:</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private val one: FiveOne = mockk(relaxed = true, relaxUnitFun = true)</pre>



<h2 class="wp-block-heading">Partial Mocking</h2>



<p>Nextly, let&#8217;s focus on the <strong>partial mocking.</strong></p>



<p>This technique, on the other hand, allows us to <strong>invoke the actual function</strong>.</p>



<p>Let&#8217;s take a look at the example of a new class to test:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Six(
    private val one: SixOne,
) {
    fun funToTest(): String {
        one.returnInt()
        return one.returnString()
    }
}

class SixOne {
    fun returnInt(): Int = 10
    fun returnString(): String = "Some String"
}</pre>



<p>As we can see, apart from the names, it works exactly the same as previously.</p>



<p>So, let&#8217;s take a look at the test:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class SixTest {

    private val one: SixOne = mockk()
    private val five = Six(one)

    @Test
    fun `should invoke actual functions`() {
        every { one.returnInt() } answers { callOriginal() }
        every { one.returnString() } answers { callOriginal() }

        val result = five.funToTest()

        assertEquals("Some String", result)
    }
}</pre>



<p>As we can see, in MockK, we can use the <code>answers { callOriginal() }</code>&nbsp; to invoke the actual function. And that&#8217;s why we get <em>&#8220;Some String&#8221;</em> value here.</p>



<h2 class="wp-block-heading">MockK Spy</h2>



<p>As the last step, let&#8217;s take a look at the <strong>spies</strong>. What are they?</p>



<p>Well, they are a mix of real objects with mocks. Whenever we do not specify any stubbing, the actual function is invoked.</p>



<p>So, the main difference between spies and partial mocking is that for a spy, the original function is invoked if we don&#8217;t write anything. In partial mocking, we must be explicit.</p>



<p>Let&#8217;s take a look at the code to test then. Again, this is a 1:1 copy of previous examples:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Seven(
    private val one: SevenOne,
) {
    fun funToTest(): String {
        one.returnInt()
        return one.returnString()
    }
}

class SevenOne {
    fun returnInt(): Int = 10
    fun returnString(): String = "Some String"
}</pre>



<p>Following, let&#8217;s implement a simple test with a MockK spy then:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class SevenTest {

    private val one: SevenOne = spyk(SevenOne())

    private val five = Seven(one)

    @Test
    fun `should invoke actual functions`() {
        val result = five.funToTest()

        assertEquals("Some String", result)
    }
}</pre>



<p>And we can see the interesting difference here- we pass the instance of the dependent object to the <code>spyk</code> . And although underneath a copy of that object will be used rather than the passed instance, this shows that <strong>spies are actual objects with mocking capabilities.</strong></p>



<p>Additionally, we can use a similar notation to <code>mockk</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private val one: SevenOne = spyk()
// or 
private val one = spyk&lt;SevenOne>()</pre>



<p>In this case, the default constructor will be invoked.</p>



<p>And if you are wondering when to use spies, and when to choose partial mocks, then I would say that partial mocks will be better whenever actual calls are rare, almost exceptional. If since the very beginning we want to mix actual resposnes with stubs, then spies will be more optiomal option.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>That&#8217;s all for the fourth article in a series in which we learned how to deal with MockK spies, relaxed mocks, and partial mocking.</p>



<p>Awesome! And without any further ado, let&#8217;s head to the next lesson:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li><a href="MockK: Objects, Top-Level, and Extension Functions [3/5]">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li>MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<p></p>
<p>The post <a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spy, Relaxed Mock, and Partial Mocking [4/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MockK: Objects, Top-Level, and Extension Functions [3/5]</title>
		<link>https://blog.codersee.com/mockk-objects-top-level-extension-functions/</link>
					<comments>https://blog.codersee.com/mockk-objects-top-level-extension-functions/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 04 Mar 2025 17:55:29 +0000</pubDate>
				<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[MockK]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=17512691</guid>

					<description><![CDATA[<p>In the third artcile in a series, we are going to focus on Kotlin objects, top-level and extension functions in MockK. </p>
<p>The post <a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>This tutorial is a great example of why MockK is an excellent choice for Kotlin and how easy we can work with Kotlin features, such as the previously mentioned objects.</p>



<p>Of course, you can find the rest of the series on my blog, too:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li>MockK: Objects, Top-Level, and Extension Functions [3/5]</li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<h2 class="wp-block-heading" id="h-video-content">Video Content</h2>



<p>As always, if you prefer a video content, then please check out my latest YouTube video:</p>


<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/"><img decoding="async" src="https://blog.codersee.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2FaesDHmuny_0%2Fhqdefault.jpg" alt="YouTube Video"></a><br /><br /><figcaption></figcaption></figure>


<h2 class="wp-block-heading" id="h-kotlin-objects-and-mockk">Kotlin Objects and MockK</h2>



<p>Let&#8217;s start everything by explaining <strong>how to mock Kotlin objects in MockK</strong>.</p>



<p>And as you know, objects are pretty specific, so we are going to see two, different examples and approaches.</p>



<h3 class="wp-block-heading" id="h-mockkobject"><code>mockkObject</code></h3>



<p>Let&#8217;s introduce a simple example with an object:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class One {
    fun funToTest(): UUID = SomeObject.generateId()
}

object SomeObject {
    fun generateId(): UUID = UUID.randomUUID()
}</pre>



<p>It is not rocket science, right? We are going to simply test the function that should return the UUID generated by <code>SomeObject</code> function.</p>



<p>So, if we would like to mock that UUID to gain more control over the behavior, then we can use the <code>mockkObject</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class OneTest {

    private val one = One()

    @Test
    fun `should return mocked ID`() {
        val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

        mockkObject(SomeObject)
        every { SomeObject.generateId() } returns id

        val result = one.funToTest()

        assertEquals(id, result)
    }
}</pre>



<p>The above test succeeds, and we can see that we define stubbing just like with every mock.</p>



<p>Moreover, if we add <code>mockkObject</code> inside the function, it will not affect the scope of other tests:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class OneTest {

    private val one = One()

    @Test
    fun `should return mocked ID`() {
        val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

        mockkObject(SomeObject)
        every { SomeObject.generateId() } returns id

        val result = one.funToTest()

        assertEquals(id, result)
    }

    @Test
    fun `should fail returning mocked ID`() {
        val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

        val result = one.funToTest()

        assertEquals(id, result)
    }
}</pre>



<p>This time, the second test fails because <code>SomeObject</code> returns a <strong>random value.</strong></p>



<p>Additionally, if we use the <code>mockkObject</code> , but we don&#8217;t provide stubbing, <strong>MockK will not throw any exception:</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should fail returning mocked ID`() {
    val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

    mockkObject(SomeObject)
    val result = one.funToTest()

    assertEquals(id, result)
}</pre>



<p>The above test runs just like <code>mockkObject(SomeObject)</code> does not exist. As a result, we get a random UUID.</p>



<p>So, we must be cautious about that.</p>



<h3 class="wp-block-heading"><code>unmockkObject</code></h3>



<p>Although I highly doubt we should ever use that, MockK allows us to &#8220;unmock&#8221; the object with <code>unmockkObject</code> function.</p>



<p>How does it work?</p>



<p>Let&#8217;s analyze the below snippet:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should illustrate unmockkObject`() {
    val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

    mockkObject(SomeObject)
    every { SomeObject.generateId() } returns id

    assertEquals(id, one.funToTest())

    unmockkObject(SomeObject)
    assertEquals(id, one.funToTest())
}</pre>



<p>In this example, the first assertion succeeds. However, the second <code>assertEquals</code> fails due to <code>unmockkObject</code> that reverts our mock.</p>



<p>So, again, during the second call, a random UUID is generated.</p>



<h3 class="wp-block-heading">Create Mock Object Instance</h3>



<p>I know, this title sounds simply weird.</p>



<p>Nevertheless, let&#8217;s take a look at another class- <code>Two</code> :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Two(
    private val someObject: SomeObject,
) {
    fun funToTest(): UUID = someObject.generateId()
}</pre>



<p>This time, we inject our <code>SomeObject</code> through the constructor.</p>



<p>And for consistency, in MockK, we can mock that just like a simple class:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class TwoTest {

    private val someObject = mockk&lt;SomeObject>()
    private val two = Two(someObject)

    @Test
    fun `should return mocked ID`() {
        val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

        every { someObject.generateId() } returns id

        val result = two.funToTest()

        assertEquals(id, result)
    }
}</pre>



<p>But, <strong>we must remember about two, important things in this case.</strong></p>



<p>Firstly, we <strong>must provide a stubbing</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should fail due to missing stubbing`() {
    val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

    val result = two.funToTest()

    assertEquals(id, result)
}</pre>



<p>So, just like with classes, the above test fails due to missing stubbing!</p>



<p>Secondly, when defining stubbing, we <strong>must use the instance</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should fail due to incorrect stubbing`() {
    val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

    every { SomeObject.generateId() } returns id

    val result = two.funToTest()

    assertEquals(id, result)
}</pre>



<p>As we can see, we cannot refer to the <code>SomeObject</code> anymore.</p>



<p>So, as always, the choice is up to you. 🙂</p>



<h2 class="wp-block-heading">MockK and Top-Level Functions</h2>



<p>With all of that said about objects, let&#8217;s take a look at how we can deal with another Kotlin feature, <strong>top-level functions</strong>, in MockK.</p>



<p>As the first step, let&#8217;s take a look at the code to test:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Three {
    fun funToTest(): UUID = generateId()
}

fun generateId(): UUID = UUID.randomUUID()</pre>



<p>This time, instead of the object and its function, we&#8217;re dealing with top-level <code>generateId</code> .</p>



<p>And from the MockK perspective, everything looks pretty much the same as with objects:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class ThreeTest {

    private val three = Three()

    @Test
    fun `should return mocked ID`() {
        val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

        mockkStatic(::generateId)
        every { generateId() } returns id

        val result = three.funToTest()

        assertEquals(id, result)
    }
}</pre>



<p>As we can see, we use the <code>mockkStatic</code> and we simply provide our stubbing.</p>



<p>And just like in the first approach in objects, nothing happens if we define the <code>mockkStatic</code> , but we don&#8217;t set the stubbing. The random UUID is generated:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should fail due to missing stubbing`() {
    val id = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

    mockkStatic(::generateId)

    val result = three.funToTest()

    assertEquals(id, result)
}</pre>



<p>Lastly, I just wanted to mention that we have a similar function- <code>clearStaticMockk</code>&#8211; on the table, too😉</p>



<h2 class="wp-block-heading">Extension Functions Support</h2>



<p>As the last thing in this article, let&#8217;s take a look at the example leveraging the extension function:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Four {
    fun funToTest(): String = "abc".withCustomCase()
}

fun String.withCustomCase(): String = this.uppercase()</pre>



<p>It does not make too much sense, but we can clearly see that our extension function should return an uppercase String value.</p>



<p>And to mock this case in MockK, we can use <code>mockkStatic</code> once again:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class FourTest {

    private val four = Four()

    @Test
    fun `should return codersee`() {
        mockkStatic(String::withCustomCase)
        every { "abc".withCustomCase() } returns "codersee"
        every { "xyz".withCustomCase() } returns "not-codersee"

        val result = four.funToTest()

        assertEquals("codersee", result)
    }
}</pre>



<p>The really interesting part in the above snippet is that the String value <strong>must match!</strong></p>



<p>Additionally, MockK allows us to mock extension functions defined in a class.</p>



<p>Nevertheless, in my opinion this case is so rare, that I will skip it. And if you really need to check it, then take a look at the documentation <a href="https://mockk.io/#extension-functions" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>That&#8217;s all for the third article, in which we learned how to deal with Kotlin objects, top-level and extension functions in MockK.</p>



<p>Great job, and without any further ado, let&#8217;s head to the next lesson:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li>MockK: Objects, Top-Level, and Extension Functions [3/5]</li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>
<p>The post <a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/mockk-objects-top-level-extension-functions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Verification in MockK [2/5]</title>
		<link>https://blog.codersee.com/verification-mockk/</link>
					<comments>https://blog.codersee.com/verification-mockk/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 04 Mar 2025 17:55:20 +0000</pubDate>
				<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[MockK]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=17512671</guid>

					<description><![CDATA[<p>In the second article in a MockK Kotlin series, we are going to learn more about various verification techniques.</p>
<p>The post <a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>To be more specific, we are going to work with both <em>verification</em> and <em>capturing</em>&#8211; MockK Kotlin features, allowing us to perform assertions against our mocks.</p>



<p>To view other articles in this series, please take a look at:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li>Verification in MockK [2/5]</li>



<li><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level and Extension Functions [3/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<h2 class="wp-block-heading" id="h-video-content">Video Content</h2>



<p>As always, if you prefer a video content, then please check out my latest YouTube video:</p>


<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><a href="https://blog.codersee.com/verification-mockk/"><img decoding="async" src="https://blog.codersee.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2FTVponpWSKGE%2Fhqdefault.jpg" alt="YouTube Video"></a><br /><br /><figcaption></figcaption></figure>


<h2 class="wp-block-heading" id="h-why-do-we-need-verification">Why Do We Need Verification?</h2>



<p>At this point, you may wonder why we need to do anything else besides what we did previously. We configured mocks, and they worked; we made the necessary assertions. </p>



<p>Then what is the point of anything else?</p>



<p>Well, our logic is pretty clear and <strong>predictable</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun createUser(email: String, password: String): UUID {
    userRepository.findUserByEmail(email)
        ?.let { throw IllegalArgumentException("User with email $email already exists") }

    return userRepository.saveUser(email, password)
        .also { userId ->
            emailService.sendEmail(
                to = email,
                subject = "Welcome to Codersee!",
                body = "Welcome user: $userId."
            )
        }
}</pre>



<p>And by predictable, I mean that we see that every function will be invoked at most 1 time. That no other functions are invoked when we throw the exception. And I do not see any possibility that <code>saveUser</code> somehow would trigger before <code>findUserByEmail</code>.</p>



<p>But sometimes, that&#8217;s not the case.</p>



<p>Sometimes mocks may be invoked a variable number of times depending on some response, right? For example, when we call some user endpoint, we get a list of users, and then we fetch something for each user. </p>



<p>Another time, the order may be affected by the algorithm. And yet another time, it may be simply a spaghetti you inherited from someone else😉</p>



<p>And in a moment, we will learn what exactly we can do in our tests.</p>



<h2 class="wp-block-heading">Verification with <code>eq</code></h2>



<p>Before we head to the actual functions, let me share a first MockK verification tip: <strong>prefer <code>eq</code> matchers wherever possible.</strong></p>



<p>To better visualize, let&#8217;s recap the test example once again:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should throw IllegalArgumentException when user with given e-mail already exists`() {
    val email = "contact@codersee.com"
    val password = "pwd"

    val foundUser = User(UUID.randomUUID(), email, password)
    every { userRepository.findUserByEmail(email) } returns foundUser

    assertThrows&lt;IllegalArgumentException> {
        service.createUser(email, password)
    }
}</pre>



<p>We clearly see that <code>foundUser</code> will be returned only if the <code>findUserByEmail</code> is invoked with <code>contact@codersee.com</code></p>



<p>And this is already a kind of verification. Because if we would use <code>any()</code> , or <code>any&lt;String&gt;()</code> , the test would still pass. However,<strong> it would pass even if our logic sent a password there by mistake!</strong></p>



<p>So I guess you see my point here. For such cases, I would go for <code>eq</code> matcher.</p>



<h2 class="wp-block-heading">Various MockK Verifications</h2>



<p>And with all of that said, we can finally take a look at various, actual verifications in MockK.</p>



<p>For that purpose, let&#8217;s introduce a more dummy example that will help us to focus on the topic without unwanted code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class A (
    private val b: B,
    private val c: C
) {
    fun funToTest(): Int {
        return 5
    }
}

class B {
    fun funFromB(): Int = 10
}

class C {
    fun funFromC(): String = "Hi!"
}</pre>



<h3 class="wp-block-heading"><code>verify</code></h3>



<p>Let&#8217;s start with the simplest one- <code>verify</code> .</p>



<p>And for that, let&#8217;s update the <code>funToTest</code> and write a simple test for it:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun funToTest(): Int {
    repeat(10) { b.funFromB() }
    repeat(5) { c.funFromC() }
    return 5
}

@Test
fun `should return 5 without any verification`() {
    every { b.funFromB() } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)
}</pre>



<p>When we run the test, it succeeds. Moreover, we can clearly see that we can define stubbing once. Even though functions are invoked multiple times.</p>



<p>With the <code>verify</code> , we can make sure that they were invoked a specific number of times:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 5 with verification and confirmation`() {
    every { b.funFromB() } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verify(exactly = 10) { b.funFromB() }
    verify(atLeast = 5) { c.funFromC() }

    confirmVerified(b, c)
}</pre>



<p>We can use <code>exactly</code> , <code>atLeast</code> , <code>atMost</code> &#8211; the choice is up to you.</p>



<p>Additionally, if we would like to set some arbitraty <strong>timeout</strong>, then this is our go-to function.</p>



<h3 class="wp-block-heading"><code>confirmVerified</code></h3>



<p>Moreover, we should use <code>verify</code> in combination with <code>confirmVerified</code> .</p>



<p>This way, we additionally check if our test code verified all invoked functions.</p>



<p>If we get rid of <code>verify(atLeast = 5) { c.funFromC() }</code> and rerun the test, we will see:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Verification acknowledgment failed

Verified call count: 0
Recorded call count: 5


Not verified calls:
1) C(#2).funFromC()
2) C(#2).funFromC()
3) C(#2).funFromC()
4) C(#2).funFromC()
5) C(#2).funFromC()</pre>



<p>So, as we can see, this is a great way to double-check our test assumptions (testing a test?🙂).</p>



<h3 class="wp-block-heading"><code>checkUnnecessaryStub</code></h3>



<p>Speaking of testing the test- we can additionally check if there are no unused stubbings.</p>



<p>For that purpose, let&#8217;s slightly update the example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class A(
    private val b: B,
    private val c: C
) {
    fun funToTest(): Int {
        repeat(10) { b.funFromB(7) }
        repeat(5) { c.funFromC() }
        return 5
    }
}

class B {
    fun funFromB(some: Int): Int = 10
}

class C {
    fun funFromC(): String = "Hi!"
}</pre>



<p>So this time, <code>funFromB</code> will always be invoked with <code>7</code> .</p>



<p>And if we make our test this way:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 5 with verification and confirmation`() {
    every { b.funFromB(7) } returns 1
    every { b.funFromB(6) } returns 2 // unwanted
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verify(exactly = 10) { b.funFromB(7) }
    verify(atLeast = 5) { c.funFromC() }

    confirmVerified(b, c)
    checkUnnecessaryStub(b, c)
}</pre>



<p>Then MockK will be complaining a bit:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">1) B(#1).funFromB(eq(6)))
java.lang.AssertionError: Unnecessary stubbings detected.
Following stubbings are not used, either because there are unnecessary or because tested code doesn't call them :

1) B(#1).funFromB(eq(6)))</pre>



<h3 class="wp-block-heading"><code>verifyCount</code></h3>



<p>When it comes to counts, we can use the <code>verifyCount</code> function instead:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 5 with verifyCount`() {
    every { b.funFromB(7) } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verifyCount {
        10 * { b.funFromB(7) }
        (4..5) * { c.funFromC() }
    }
    confirmVerified(b, c)
}</pre>



<p>This allows us to achieve an even cleaner test with beautiful Kotlin DSL.</p>



<p>Nevertheless, we still have to invoke <code>confirmVerified</code> separately.</p>



<h3 class="wp-block-heading"><code>verifyAll/verifyOrder/verifySequence</code></h3>



<p>Sometimes, we can use <code>verifyAll</code> , <code>verifyOrder</code> , and <code>verifySequence</code> to make the code slightly cleaner.</p>



<p>The <code>verifyAll</code> checks if all calls happened, but it does not verify the order:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 5 with verifyAll`() {
    every { b.funFromB(7) } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verifyAll {
        c.funFromC()
        b.funFromB(7)
    }
}</pre>



<p>So, the above function will work like a charm.</p>



<p>On the other hand, if we use the <code>verifyOrder</code> , it won&#8217;t work anymore, and we will have to provide a valid order:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 5 with verifyOrder`() {
    every { b.funFromB(7) } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verifyOrder {
        b.funFromB(7)
        c.funFromC()
    }
}</pre>



<p>Lastly, the <code>verifySequence</code> will work similar to <code>verifyOrder</code> , but it will force us to provide the right amount of times in the right order.</p>



<p>So, to make the test work, we would need to do a small tweak:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 5 with verifySequence`() {
    every { b.funFromB(7) } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verifySequence {
        repeat(10) { b.funFromB(7) }
        repeat(5) { c.funFromC() }
    }
}</pre>



<p>The important thing to mention is that if in our <code>verifyAll</code> or <code>verifySequence</code> block we covered all mocks, then we don&#8217;t need to add <code>confirmVerified</code> .</p>



<p>But, <strong>unfortunately</strong>, this will succeed:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should fail due to missing verification`() {
    every { b.funFromB(7) } returns 1
    every { c.funFromC() } returns ""

    val result = a.funToTest()

    assertEquals(5, result)

    verifySequence {
        repeat(10) { b.funFromB(7) }
    }
}</pre>



<p>And we must guard ourselves with <code>confirmVerified(c)</code> .</p>



<p>However, if we do the <code>b</code> and <code>c</code> check inside. Then the <code>confirmedVerified</code> is not needed anymore.</p>



<h2 class="wp-block-heading">MockK capturing</h2>



<p>Lastly, I would like to show you one more interesting MockK feature useful in verification- the <strong>capturing</strong>.</p>



<p>Let&#8217;s imagine a new function inside the <code>B</code> class:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class B {
    fun anotherFunFromB(some: Int) {}
}</pre>



<p>Now, the <code>anotherFunToTest</code> invokes it using the random value:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun anotherFunToTest(): Int {
    b.anotherFunFromB(Random.nextInt())
    return 3
}</pre>



<p>So, if we write a test this way:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 3`() {
    justRun { b.anotherFunFromB(any()) }

    val result = a.anotherFunToTest()

    assertEquals(3, result)
}</pre>



<p>We clearly see, that we cannot access this value in any way, right? It is not returned from the function itself. We cannot control it with other mock, too.</p>



<p>Thankfully, we can introduce a <strong>slot </strong>and capture the value on the fly:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 3`() {
    val randomSlot = slot&lt;Int>()

    justRun { b.anotherFunFromB(capture(randomSlot)) }

    val result = a.anotherFunToTest()

    println("Random value: ${randomSlot.captured}")
    assertEquals(3, result)
}</pre>



<p>This way, the stubbing works just like <code>any()</code> ,but additionally, we can access the random value with <code>captured</code> .</p>



<p>And although this may not be a clear verification, in some cases, it can be really helpful.</p>



<h3 class="wp-block-heading">Summary</h3>



<p>That&#8217;s all for this article about verification in MockK.</p>



<p>We covered various approaches, techniques, and at this point I am pretty sure you will be able to pick the right one for your test cases.</p>



<p>Without any further ado, let&#8217;s head to the next article in this series:</p>



<ul class="wp-block-list">
<li><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a></li>



<li>Verification in MockK [2/5]</li>



<li><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<p></p>
<p>The post <a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/verification-mockk/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Getting Started with MockK in Kotlin [1/5]</title>
		<link>https://blog.codersee.com/getting-started-with-mockk-kotlin/</link>
					<comments>https://blog.codersee.com/getting-started-with-mockk-kotlin/#comments</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 04 Mar 2025 17:55:01 +0000</pubDate>
				<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[MockK]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=17512637</guid>

					<description><![CDATA[<p>In this, first article in a series dedicated to MockK and Kotlin, we will learn how to create mocks, define stubbings and utilize matchers.</p>
<p>The post <a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Before we head there, we will take a quick look at what exactly mocking is, and the differences between several terms that often lead to confusion. Thanks to that, we will have a solid foundation before diving into the <strong>MockK and Kotlin </strong>topics.</p>



<ul class="wp-block-list">
<li>Getting Started with MockK in Kotlin [1/5]</li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>If you enjoy this content, then check out my <a href="https://codersee.com/courses/ktor-server-pro/">Ktor Server PRO</a> course- the most comprehensive Ktor guide in the market. You&#8217;re gonna love it! 🙂 </p>
</blockquote>



<h2 class="wp-block-heading" id="h-video-content">Video Content</h2>



<p>As always, if you prefer a video content, then please check out my latest YouTube video:</p>


<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/"><img decoding="async" src="https://blog.codersee.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2F4prbIk2TuX4%2Fhqdefault.jpg" alt="YouTube Video"></a><br /><br /><figcaption></figcaption></figure>


<h2 class="wp-block-heading" id="h-why-do-we-need-mocking">Why Do We Need Mocking?</h2>



<p>Long story short, we need mocking to isolate the unit / the system under test.</p>



<p>Sounds confusing? No worries.</p>



<p>Let&#8217;s take a look at the typical example of a function:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="576" src="http://blog.codersee.com/wp-content/uploads/2025/03/mocking_mockk_system_under_test_dependent_on_component-1024x576.png" alt="Image is an explainer for MockK and presents a visualization of system under test / unit and dependend on components" class="wp-image-17512639" srcset="https://blog.codersee.com/wp-content/uploads/2025/03/mocking_mockk_system_under_test_dependent_on_component-1024x576.png 1024w, https://blog.codersee.com/wp-content/uploads/2025/03/mocking_mockk_system_under_test_dependent_on_component-300x169.png 300w, https://blog.codersee.com/wp-content/uploads/2025/03/mocking_mockk_system_under_test_dependent_on_component-768x432.png 768w, https://blog.codersee.com/wp-content/uploads/2025/03/mocking_mockk_system_under_test_dependent_on_component-1536x864.png 1536w, https://blog.codersee.com/wp-content/uploads/2025/03/mocking_mockk_system_under_test_dependent_on_component.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>So, our function A- the one we would like to focus on in our test- calls both B and C. It can happen sequentially or simultaneously; it doesn&#8217;t matter.</p>



<p>What matters is that when we want to test A, we want to see its behavior in different cases. How does it behave when B returns (for instance) user data successfully? What happens in case of a null value? Does it handle exceptions gracefully?</p>



<p>And to avoid spending countless hours on manual setup, we use the <strong>mocking </strong>technique to simulate different scenarios. Mostly with the help of libraries, like MockK.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>The important thing to remember is that mocking is not limited to functions. A, B, and C may as well represent services.</p>



<p>And in various sources, A will be referred to as the System Under Test (SUT), whereas B, and C will be Depended On Component (DOC).</p>
</blockquote>



<h2 class="wp-block-heading" id="h-mocking-stubbing-test-doubles">Mocking, Stubbing, Test Doubles</h2>



<p>Frankly, please skip this section if this is your first time with mocking or MockK. I truly believe you will benefit more from focusing on learning MockK-related concepts than slight differences in wording.</p>



<p>Anyway, from the chronicler&#8217;s duty, let me illustrate a few concepts:</p>



<ul class="wp-block-list">
<li><strong>stub </strong>is a fake object that returns hard-coded answers. Typically, we use it to return some value, but we don&#8217;t care about additional info, like how many times it was invoked, etc.</li>



<li><strong>mock</strong> is pretty similar, but this time, we can verify interactions, too. For example, to see if this was invoked with a particular ID value, exactly N times.</li>



<li><strong>stubbing</strong> means setting up a <em>stub</em> or a <em>mock</em> so that a particular method returns some value or throws an exception</li>



<li><strong>mocking</strong> means creating/using a <em>mock</em></li>



<li>and lastly, we use the <strong>test doubles </strong>term for any kind of replacement we use in place of a real object in your tests (that terms comes stund doubles in movies).</li>
</ul>



<p>And if you are looking for a really deep dive, I invite you to <a href="https://martinfowler.com/articles/mocksArentStubs.html" target="_blank" rel="noreferrer noopener">Martin Fowler&#8217;s article</a>.</p>



<h2 class="wp-block-heading" id="h-mockk-imports">MockK Imports</h2>



<p>With all of that said, let&#8217;s head to the practice part. </p>



<p>Firstly, let&#8217;s define the necessary imports for MockK.</p>



<p>We will be working with a plain Kotlin / Gradle project with JUnit 5, so our <code>build.gradle.kts</code> dependencies should look as follows:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dependencies {
    testImplementation("io.mockk:mockk:1.13.17")
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}</pre>



<p>The <code>io.mockk:mockk</code> is the only thing we need when working with MockK (unless we want to work with couroutines- but I will get back to that in the fifth lesson).</p>



<h2 class="wp-block-heading" id="h-tested-code">Tested Code</h2>



<p>Then, let&#8217;s take a look at the code we are supposed to test:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">data class User(val id: UUID, val email: String, val passwordHash: String)

class UserRepository {
    fun saveUser(email: String, passwordHash: String): UUID =
        UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")

    fun findUserByEmail(email: String): User? =
        User(
            id = UUID.fromString("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"),
            email = "found@codersee.com",
            passwordHash = "foundPwd"
        )
}

class EmailService {
    fun sendEmail(to: String, subject: String, body: String) {
        println("Sending body $body to $to with subject $subject")
    }
}

class UserService(
    private val userRepository: UserRepository,
    private val emailService: EmailService,
) {

    fun createUser(email: String, password: String): UUID {
        userRepository.findUserByEmail(email)
            ?.let { throw IllegalArgumentException("User with email $email already exists") }

        return userRepository.saveUser(email, password)
            .also { userId ->
                emailService.sendEmail(
                    to = email,
                    subject = "Welcome to Codersee!",
                    body = "Welcome user: $userId."
                )
            }
    }
}</pre>



<p>As we can see, we have a simple example of a <code>UserService</code> with one function- <code>createUser</code> . The service and the function that we will focus on in our tests.</p>



<p>And although <code>UserRepository</code> and <code>EmailService</code> look pretty weird, the <code>createUser</code> is more or less something we can find in our real-life code. We check if the given <code>email</code> is taken, and if that&#8217;s the case, we throw an exception. Otherwise, we save the user and send a notification e-mail.</p>



<h2 class="wp-block-heading" id="h-positive-amp-negative-scenario">Positive &amp; Negative Scenario</h2>



<p>Following, let&#8217;s do something different compared to other content about MockK. Let&#8217;s start by taking a look at the final result, and then we will see how we can get there.</p>



<p>So, firstly, let&#8217;s add the negative scenario:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class AwesomeMockkTest {

    private val userRepository: UserRepository = mockk()
    private val emailService = mockk&lt;EmailService>()

    private val service = UserService(userRepository, emailService)

    @Test
    fun `should throw IllegalArgumentException when user with given e-mail already exists`() {
        val email = "contact@codersee.com"
        val password = "pwd"

        val foundUser = User(UUID.randomUUID(), email, password)
        every { userRepository.findUserByEmail(email) } returns foundUser

        assertThrows&lt;IllegalArgumentException> {
            service.createUser(email, password)
        }

        verifyAll { userRepository.findUserByEmail(email) }
    }
}</pre>



<p>As we can see, we start all by defining dependencies for <code>UserService</code> as MockK mocks, and then we simply inject them through the constructor.</p>



<p>After that, we add our JUnit 5 test that asserts if the <code>createUser</code> function has thrown an exception, nothing unusual. The &#8220;unusual&#8221; part here is the <em>every</em> and <em>verifyAll</em> &#8211; those two blocks come from MockK, and we will get back to them in a moment.</p>



<p>With that done, let&#8217;s add one more test:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return UUID when user with given e-mail successfully created`() {
    val email = "contact@codersee.com"
    val password = "pwd"
    val createdUserUUID = UUID.randomUUID()

    every { userRepository.findUserByEmail(email) } returns null
    every { userRepository.saveUser(email, password) } returns createdUserUUID
    every {
        emailService.sendEmail(
            to = email,
            subject = "Welcome to Codersee!",
            body = "Welcome user: $createdUserUUID."
        )
    } just runs

    val result = service.createUser(email, password)

    assertEquals(createdUserUUID, result)

    verifyAll {
        userRepository.findUserByEmail(email)
        userRepository.saveUser(email, password)
        emailService.sendEmail(
            to = email,
            subject = "Welcome to Codersee!",
            body = "Welcome user: $createdUserUUID."
        )
    }
}</pre>



<p>This time, we test the positive scenario, in which the user was not found by the <code>e-mail</code> and was created successfully.</p>



<h2 class="wp-block-heading">Defining MockK Mocks</h2>



<p>With all of that done, let&#8217;s start breaking down things here.</p>



<p>Let&#8217;s take a look at what we did first:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private val userRepository: UserRepository = mockk()
private val emailService = mockk&lt;EmailService>()

private val service = UserService(userRepository, emailService)</pre>



<p>So, one of the approaches to define objects as <strong>mocks</strong> with MockK is by using the <code>mockk</code> function. </p>



<p>It is a generic function. So that&#8217;s why I presented both ways to invoke it. But please treat that as an example. In real life, I suggest you stick to either <code>mockk()</code> or <code>mockk&lt;EmailService&gt;()</code> for a cleaner code.</p>



<p>Alternatively, we can achieve exactly the same with MockK annotations:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@ExtendWith(MockKExtension::class)
class AwesomeMockkTest {

  @MockK
  lateinit var userRepository: UserRepository

  @MockK
  lateinit var emailService: EmailService

  @InjectMockKs
  lateinit var service: UserService

}</pre>



<p>The preferred approach is totally up to you. The important thing to mention is that the <code>@ExtendWith(MockKExtension::class)</code> comes from <strong>JUnit 5</strong>.</p>



<p>And for the <strong>JUnit 4</strong>, we would implement a rule:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class AwesomeMockkTest {
  @get:Rule
  val mockkRule = MockKRule(this)

  @MockK
  lateinit var userRepository: UserRepository

  @MockK
  lateinit var emailService: EmailService

  @InjectMockKs
  lateinit var service: UserService

}</pre>



<h2 class="wp-block-heading">Missing Stubbing</h2>



<p>At this point, we know that we don&#8217;t use real objects, but mocks.</p>



<p>Let&#8217;s try to run our test without defining any behavior:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should throw IllegalArgumentException when user with given e-mail already exists`() {
    val email = "contact@codersee.com"
    val password = "pwd"

    assertThrows&lt;IllegalArgumentException> {
        service.createUser(email, password)
    }

    verifyAll { userRepository.findUserByEmail(email) }
}</pre>



<p>In the console log, we should see the following:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Unexpected exception type thrown, expected: &lt;java.lang.IllegalArgumentException&gt; but was: &lt;io.mockk.MockKException&gt;</p>



<p>Expected :class java.lang.IllegalArgumentException</p>



<p>Actual :class io.mockk.MockKException</p>
</blockquote>



<p>Well, the issue is that when we do not specify a stubbing for a function that was invoked, MockK <strong>throws an exception</strong>.</p>



<p>But our test logic looks already for exception, so that&#8217;s why we got a message that this is simply an unexpected one.</p>



<p>Without the <code>assertThrows</code> , the message would be more obvious:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>no answer found for UserRepository(#1).findUserByEmail(contact@codersee.com) among the configured answers: (UserRepository(#1).saveUser(eq(contact@codersee.com), eq(pwd))))</p>



<p>io.mockk.MockKException: no answer found for UserRepository(#1).findUserByEmail(contact@codersee.com) among the configured answers: (UserRepository(#1).saveUser(eq(contact@codersee.com), eq(pwd))))</p>
</blockquote>



<p>So, <strong>lesson one</strong>: whenever we see a similar message, it means that our mock function was invoked, but we haven&#8217;t defined any stubbing.</p>



<h2 class="wp-block-heading" id="h-stubbing-in-mockk">Stubbing in MockK</h2>



<p>And we already saw how we can define a stubbing, but let&#8217;s take a look once again:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">val foundUser = User(UUID.randomUUID(), email, password)
every { userRepository.findUserByEmail(email) } returns foundUser</pre>



<p>We can read the above function as &#8220;return <code>foundUser</code> every time the <code>findUserByEmail</code> function is invoked with this, specific email value&#8221;.</p>



<p>When we run the test now, everything is working fine. Because in our logic, if the <code>findUserByEmail</code> returns a not null value, an exception is thrown. So, no more functions are invoked. In other words, <strong>no more interactions with our mock</strong> object😉 Also, our email value matches.</p>



<p>And most of the time, this is how I would suggest defining stubbing. This way, we also make sure that the exact value of <code>email</code> is passed.</p>



<p>When it comes to the answer part, <code>returns foundUser</code>, we can also use alternatives, like:</p>



<ul class="wp-block-list">
<li><code>answers { code }</code> &#8211; to define a block of code to run (and/or return a value)</li>



<li><code>throws ex</code> &#8211; to throw exception</li>



<li>and many, many more (I will put a link to the docs at the end of this article)</li>
</ul>



<h2 class="wp-block-heading">MockK Matchers</h2>



<p>The above stubbing expects that the <code>email</code> value will be equal to what we define.</p>



<p>Technically, it is the equivalent of using the <code>eq</code> function:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> every { userRepository.findUserByEmail(eq(email)) } returns foundUser</pre>



<p>And <code>eq</code> uses the <code>deepEquals</code> function to compare the values.</p>



<p>But sometimes, we do not want to, or we cannot define the exact value to match.</p>



<p>Let&#8217;s imagine that some function is invoked 20 times with various values. Technically, we could define all 20 matches.</p>



<p>But instead, we use one of the many matchers available in MockK, like <code>any</code> :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> every { userRepository.findUserByEmail(any()) } returns foundUser</pre>



<p>And whereas <code>eq</code> is the most concrete one, <code>any</code> is the most generic one. The <code>foundUser</code> is returned if <code>findUserByEmail</code> is invoked with anything.</p>



<p>And MockK comes with plenty of other matchers, like:</p>



<ul class="wp-block-list">
<li><code>any(Class)</code> &#8211; to match only if an instance of a given Class is passed</li>



<li><code>isNull</code> / <code>isNull(inverse=true)</code> &#8211; for null check</li>



<li><code>cmpEq(value)</code> , <code>more(value)</code> , <code>less(value)</code> &#8211; for the <code>compareTo</code> comparisons</li>



<li>and many more that you can find in the documentation</li>
</ul>



<p>For example, let&#8217;s take a look at the <code>match</code> example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">every {
  userRepository.findUserByEmail(
    match { it.contains("@") }
  )
} returns foundUser</pre>



<p>As we can see, this way the <code>foundUser</code> will be returned only if the passed value contains <code>@</code> sign.</p>



<h2 class="wp-block-heading">Unit Functions</h2>



<p>At this point, we know how to deal with matchers and the <code>returns</code> .</p>



<p>But what if the function does not return anything? We saw that previously, so let&#8217;s take a look once again:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">every { emailService.sendEmail(any(), any(), any()) } just runs</pre>



<p>Matchers are irrelevant right now, so I replaced them with <code>any()</code> .</p>



<p>The important thing here is that <code>just runs</code> is one of the approaches.</p>



<p>Alternatively, we can achieve the same:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">every { emailService.sendEmail(any(), any(), any()) } returns Unit
every { emailService.sendEmail(any(), any(), any()) } answers { }
justRun { emailService.sendEmail(any(), any(), any()) } </pre>



<p>The choice here is totally up to you.</p>



<h2 class="wp-block-heading" id="h-summary">Summary</h2>



<p>And that&#8217;s all for our first lesson dedicated to MockK and Kotlin. </p>



<p>As I mentioned above, <a href="https://mockk.io/" target="_blank" rel="noreferrer noopener">right here</a> you can find the MockK documentation. And although I strongly encourage you to visit it, I also would suggest doing it after my series- when we cover the most important concepts:</p>



<ul class="wp-block-list">
<li>Getting Started with MockK in Kotlin [1/5]</li>



<li><a href="https://blog.codersee.com/verification-mockk/">Verification in MockK [2/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-objects-top-level-extension-functions/">MockK: Objects, Top-Level, and Extension Functions [3/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-spy-relaxed-mock-partial-mocking/">MockK: Spies, Relaxed Mocks, and Partial Mocking [4/5]</a></li>



<li><a href="https://blog.codersee.com/mockk-coroutines/">MockK with Coroutines [5/5]</a></li>
</ul>



<p></p>
<p>The post <a href="https://blog.codersee.com/getting-started-with-mockk-kotlin/">Getting Started with MockK in Kotlin [1/5]</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/getting-started-with-mockk-kotlin/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Testing Micronaut Application in Kotlin</title>
		<link>https://blog.codersee.com/testing-micronaut-appplication-kotlin/</link>
					<comments>https://blog.codersee.com/testing-micronaut-appplication-kotlin/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Wed, 10 Jan 2024 08:24:44 +0000</pubDate>
				<category><![CDATA[Micronaut]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[JUnit 5]]></category>
		<category><![CDATA[MockK]]></category>
		<category><![CDATA[REST Assured]]></category>
		<category><![CDATA[Testing]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=9508620</guid>

					<description><![CDATA[<p>In this, practical tutorial, I will show you how to test a REST API created with Micronaut, Kotlin and MongoDB.</p>
<p>The post <a href="https://blog.codersee.com/testing-micronaut-appplication-kotlin/">Testing Micronaut Application in Kotlin</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Hello and welcome to my next article, in which I will show you <strong>how to test a Micronaut application in Kotlin</strong>. </p>



<p>To be even more specific- we will work with an application that exposes a <strong>REST API</strong> and connects to <strong>MongoDB</strong>. If you would like to learn how to do that step-by-step, then you can check out <a href="https://blog.codersee.com/micronaut-with-mongodb-and-kotlin-revisited-2022/" target="_blank" rel="noreferrer noopener">my other article</a>. (But don&#8217;t worry, we will see its code snippets in this tutorial, too). </p>



<p>For testing, we&#8217;re going to use <strong>JUnit 5</strong>, <strong>MockK</strong>, <strong>REST Assured</strong>, as well as the <strong>@MicronautTest</strong> and <strong>Micronaut Test Resources</strong>.</p>



<h2 class="wp-block-heading" id="h-video-tutorial">Video Tutorial</h2>



<p>If you prefer <strong>video content</strong>, then check out my video:</p>



<div style="text-align: center; width: 90%; margin-left: 5%;">
<a href="https://blog.codersee.com/testing-micronaut-appplication-kotlin/"><img decoding="async" src="https://blog.codersee.com/wp-content/plugins/wp-youtube-lyte/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2FH-LbDsi4qKg%2Fhqdefault.jpg" alt="YouTube Video"></a><br /><br /></p></div>



<p>If you find this content useful,<strong> please leave a subscription&nbsp;</strong> 😉</p>



<h2 class="wp-block-heading" id="h-micronaut-project-overview">Micronaut Project Overview</h2>



<p>Let&#8217;s start everything by <strong>checking the project we will test today</strong>. Of course, we will focus on the most important parts, and for the full source code, I invite you to <a href="https://github.com/codersee-blog/kotlin-micronaut-testing" target="_blank" rel="noreferrer noopener">this GitHub repository</a>.</p>



<h3 class="wp-block-heading" id="h-application-properties">Application Properties</h3>



<p>In our project, we introduce 3 application properties files: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// application.properties
micronaut.application.name=micronaut-testing

// application-mongo.properties
mongodb.uri=mongodb://localhost:27017/example

// application-test.properties
mongodb.package-names=com.codersee.model</pre>



<p>The application name is the default property inserted when generating a new project. </p>



<p>Nevertheless, the two remaining are created on purpose. With their names- <code>*mongo</code>, <code>*test</code>&#8211; we instruct Micronaut that it should consider them only when <code>mongo</code> and <code>test</code> profiles are active. </p>



<p>But why this way? Well, to avoid two issues. </p>



<h3 class="wp-block-heading" id="h-mongodb-connection-issues-with-micronaut-test-resources">MongoDB Connection Issues with Micronaut Test Resources</h3>



<p>So, let&#8217;s start everything by explaining <strong>why we don&#8217;t put the Mongo URI inside the main properties</strong>.</p>



<p>Well, when we use the Micronaut Test Resources, MongoDB support will start a MongoDB container and provide the value of the <code>mongodb.uri</code> property. </p>



<p>Nevertheless, <strong>this won&#8217;t happen</strong> when we explicitly set the URI in the application properties. And that&#8217;s why we want to make this setting available <strong>only when we set the environment to <code>mongo</code>.</strong></p>



<h3 class="wp-block-heading" id="h-codeccachekey-issue">CodecCacheKey Issue</h3>



<p>Additionally, if we don&#8217;t specify explicitly the package name, where our model classes live, we&#8217;re going to end up with the following issue when running our Micronaut tests: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[io-executor-thread-1] ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Can't find a codec for CodecCacheKey{clazz=class com.codersee.model.AppUser, types=null}.
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for CodecCacheKey{clazz=class com.codersee.model.AppUser, types=null}.
  at org.bson.internal.ProvidersCodecRegistry.lambda$get$0(ProvidersCodecRegistry.java:87)
  at java.base/java.util.Optional.orElseGet(Optional.java:364)
  at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:80)
  at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:50)
  at com.mongodb.internal.operation.Operations.createFindOperation(Operations.java:188)
...</pre>



<p>To me, looks like a bug. But thankfully, we can easily avoid that by putting that in the <code>application-test.properties</code> (which is used in tests by default).</p>



<h3 class="wp-block-heading" id="h-models">Models</h3>



<p>Following, we introduce a bunch of models:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Address.kt: 

import io.micronaut.serde.annotation.Serdeable

@Serdeable.Serializable
@Serdeable.Deserializable
data class Address(
  val street: String,
  val city: String,
  val code: Int
)

// AppUser.kt:

import io.micronaut.data.annotation.GeneratedValue
import io.micronaut.data.annotation.Id
import io.micronaut.data.annotation.MappedEntity

@MappedEntity
data class AppUser(
  @field:Id
  @field:GeneratedValue
  val id: String? = null,
  val firstName: String,
  val lastName: String,
  val email: String,
  val address: Address
)

// AppUserRequest.kt: 

import io.micronaut.serde.annotation.Serdeable

@Serdeable.Deserializable
data class AppUserRequest(
  val firstName: String,
  val lastName: String,
  val email: String,
  val street: String,
  val city: String,
  val code: Int
)

// SearchRequest.kt:

import io.micronaut.serde.annotation.Serdeable

@Serdeable.Deserializable
data class SearchRequest(val name: String)</pre>



<p>Those classes are either used to persist/retrieve data from MongoDB or when deserializing JSON payloads into the objects. </p>



<h3 class="wp-block-heading" id="h-repository">Repository</h3>



<p>Following, we have a repository layer responsible for communicating with our storage:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// AppUserRepository.kt: 

import com.codersee.model.AppUser
import io.micronaut.data.mongodb.annotation.MongoFindQuery
import io.micronaut.data.mongodb.annotation.MongoRepository
import io.micronaut.data.repository.CrudRepository

@MongoRepository
interface AppUserRepository : CrudRepository&lt;AppUser, String> {

  fun findByFirstNameEquals(firstName: String): List&lt;AppUser>

  @MongoFindQuery("{ firstName: { \$regex: :name}}")
  fun findByFirstNameLike(name: String): List&lt;AppUser>
}</pre>



<h3 class="wp-block-heading" id="h-service">Service</h3>



<p>Nextly, the service layer, where we inject the repository and encapsulate its methods: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// AppUserService.kt:

import com.codersee.model.Address
import com.codersee.model.AppUser
import com.codersee.model.AppUserRequest
import com.codersee.repository.AppUserRepository
import io.micronaut.http.HttpStatus
import io.micronaut.http.exceptions.HttpStatusException
import jakarta.inject.Singleton

@Singleton
class AppUserService(
  private val appUserRepository: AppUserRepository
) {

  fun create(userRequest: AppUserRequest): AppUser =
    appUserRepository.save(
      userRequest.toAppUserEntity()
    )

  fun findAll(): List&lt;AppUser> =
    appUserRepository
      .findAll()
      .toList()

  fun findById(id: String): AppUser =
    appUserRepository.findById(id)
      .orElseThrow { HttpStatusException(HttpStatus.NOT_FOUND, "User with id: $id was not found.") }

  fun update(id: String, updateRequest: AppUserRequest): AppUser {
    val foundUser = findById(id)

    val updatedEntity =
      updateRequest
        .toAppUserEntity()
        .copy(id = foundUser.id)

    return appUserRepository.update(updatedEntity)
  }

  fun deleteById(id: String) {
    val foundUser = findById(id)

    appUserRepository.delete(foundUser)
  }

  fun findByNameLike(name: String): List&lt;AppUser> =
    appUserRepository
      .findByFirstNameLike(name)

  private fun AppUserRequest.toAppUserEntity(): AppUser {
    val address = Address(
      street = this.street,
      city = this.city,
      code = this.code
    )

    return AppUser(
      id = null,
      firstName = this.firstName,
      lastName = this.lastName,
      email = this.email,
      address = address
    )
  }
}</pre>



<h3 class="wp-block-heading" id="h-controller">Controller </h3>



<p>And lastly, the place where we expose our REST endpoints: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// AppUserController.kt: 

import com.codersee.model.AppUserRequest
import com.codersee.service.AppUserService
import com.codersee.model.SearchRequest
import com.codersee.model.AppUser
import io.micronaut.http.HttpStatus
import io.micronaut.http.annotation.*
import io.micronaut.scheduling.TaskExecutors
import io.micronaut.scheduling.annotation.ExecuteOn

@Controller("/users")
@ExecuteOn(TaskExecutors.IO)
class AppUserController(
  private val appUserService: AppUserService
) {

  @Get
  fun findAllUsers(): List&lt;AppUser> =
    appUserService.findAll()

  @Get("/{id}")
  fun findById(@PathVariable id: String): AppUser =
    appUserService.findById(id)

  @Post
  @Status(HttpStatus.CREATED)
  fun createUser(@Body request: AppUserRequest): AppUser =
    appUserService.create(request)

  @Post("/search")
  fun searchUsers(@Body searchRequest: SearchRequest): List&lt;AppUser> =
    appUserService.findByNameLike(
      name = searchRequest.name
    )

  @Put("/{id}")
  fun updateById(
    @PathVariable id: String,
    @Body request: AppUserRequest
  ): AppUser =
    appUserService.update(id, request)

  @Delete("/{id}")
  @Status(HttpStatus.NO_CONTENT)
  fun deleteById(@PathVariable id: String) =
    appUserService.deleteById(id)
}</pre>



<h2 class="wp-block-heading" id="h-simple-kotlin-testing-in-micronaut">Simple Kotlin Testing in Micronaut</h2>



<p>Excellent. At this point, we know what exactly we are going to test. </p>



<p>And as the first approach we&#8217;re going to see will be a plain, old unit test. </p>



<p>Why? </p>



<p>Because at the end of the day, <strong>that&#8217;s what we will be dealing with most of the time</strong>. </p>



<p>So with that said, let&#8217;s take a look at the example test: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">  import com.codersee.repository.AppUserRepository
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

class AppUserServiceTest {

  private val appUserRepository = mockk&lt;AppUserRepository>()

  private val appUserService = AppUserService(appUserRepository)

  @Test
  fun `should return empty user list`() {
    every {
      appUserRepository.findAll()
    } returns emptyList()

    val result = appUserService.findAll()

    assertTrue(result.isEmpty())

    verify(exactly = 1) { appUserRepository.findAll() }
  }
}</pre>



<p>As we can see above, we simply mock (with MockK) the <em>AppUserRepository </em>and inject it into the <em>AppUserService </em>instance.</p>



<p>Then, we specify that all invocations of the <code>findAll</code> method must return the empty list (with <code>every</code>). </p>



<p>Lastly, we assert that the <code>findAll</code> method from our service returns an empty list (<code>assertTrue</code>) and that the <code>findAll</code> method from the repository was invoked only once (<code>verify</code>). </p>



<p>Nevertheless, we&#8217;re not going to spend too much here right now as this tutorial focuses on Micronaut testing in Kotlin. If you are interested in learning more about these tools, then let me know in the comments section 🙂 </p>



<h2 class="wp-block-heading" id="h-integration-testing-with-micronauttest">Integration Testing with @MicronautTest</h2>



<p>With all of that done, let&#8217;s see how the Micronaut framework helps us with testing and a few interesting cases that will help us in real life. </p>



<h3 class="wp-block-heading" id="h-what-is-a-micronauttest">What is a @MicronautTest? </h3>



<p>Let&#8217;s start everything by explaining what exactly is the <strong>@MicronautTest</strong>.</p>



<p>In simple words, it&#8217;s an annotation that we can put on the test class to mark it a Micronaut test (no sh&#8230; Sherlock 🙂 :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import io.micronaut.test.extensions.junit5.annotation.MicronautTest

@MicronautTest
class SomeTest {
  // tests
}</pre>



<p>In practice, it means that <strong>when we run a test with that annotation, it will run a real application</strong>. It will use internal Micronaut features with no mocking. So at this point, we can clearly see that this will be the right solution for <strong>integration testing.</strong></p>



<p>Moreover, this annotation can be used not only with <strong>JUnit 5</strong>, but also with <strong>Spock</strong>, <strong>Kotest</strong>, and <strong>Kotest 5</strong>. </p>



<h3 class="wp-block-heading" id="h-micronauttest-configuration-options">@MicronautTest Configuration Options </h3>



<p>The @MicronautTest allows us to configure a few properties, like the environments we want to run our test with, the packages to scan, or whether the automatic transaction wrapping should be enabled, or not:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import io.micronaut.test.extensions.junit5.annotation.MicronautTest

@MicronautTest(
  environments = ["env-1, env-2"],
  packages = ["com.codersee.somepackage"],
  transactional = false
)
class SomeTest {
  // tests
}</pre>



<p>For the full list of options, I highly encourage you to check out the docs (we can do that for instance in IntelliJ IDEA by clicking on the annotation with the left mouse button when we keep the left ctrl pressed). </p>



<h3 class="wp-block-heading" id="h-what-are-micronaut-test-resources">What Are Micronaut Test Resources? </h3>



<p>At the beginning of this tutorial, I mentioned the Micronaut Test Resources and I would like to make sure that we are on the same page with them. </p>



<p>So basically, Micronaute Test Resources <strong>integrates seamlessly with Testcontainers to provide throwaway containers for testing</strong>. But, we need to remember that Testcontainers <strong>require Docker-API compatible container runtime</strong> (in simple words- either Docker installed locally, or the Testcontainers Cloud). </p>



<p>In our case, we would like to do integration tests that require MongoDB. We could make use of the real database (which sometimes may be the case for you), provide some H2 database (not the best approach), or integrate Testcontainers. Thankfully, we don&#8217;t need to do that and the only thing we need is the appropriate import in our project: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">plugins {
    id("io.micronaut.test-resources") version "4.2.1"
}</pre>



<p>As a reminder, I want to emphasize that <strong>test resources will be used only when the <code>datasources.default.url</code> is missing.</strong> (and that&#8217;s why we removed the URI for MongoDB from tests). <strong> </strong> </p>



<h2 class="wp-block-heading" id="h-integration-tests-with-rest-assured">Integration Tests With REST Assured</h2>



<p>With all of that said, let&#8217;s combine everything together and test our Kotlin Micronaut application with JUnit 5 and REST Assured. </p>



<p>To do so, we must remember to add the necessary import: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">testImplementation("io.micronaut.test:micronaut-test-rest-assured")</pre>



<h3 class="wp-block-heading" id="h-verify-status-codes-and-headers">Verify Status Codes and Headers</h3>



<p>Let&#8217;s start with a simple request to the <code>GET /users</code> endpoint: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@MicronautTest
class AppUserControllerTestWithoutMocking {

  @Test
  fun `should return 200 OK on GET users`(spec: RequestSpecification) {
    spec
      .`when`()
      .get("/users")
      .then()
      .statusCode(200)
      .header("Content-Type", "application/json")
  }

}</pre>



<p>As I mentioned previously- by default, with @MicronautTest the real application is started. Moreover, nothing here is mocked, so the Mongo test container delivered by the Micronaut Test Resources is used.</p>



<p>Thanks to the dedicated module we added, we can inject the <code>RequestSpecification</code> into our tests and easily validate our endpoint. </p>



<p>In this case, we <strong>perform a GET request</strong> and verify that the <strong>response status code is 200 OK</strong> and the response <strong><code>Content-Type</code> header value is <code>application/json</code></strong>. </p>



<h3 class="wp-block-heading" id="h-verify-404-not-found">Verify 404 Not Found</h3>



<p>Similarly, we can verify that no entry is present in the database: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should return 404 Not Found on GET user by ID`(spec: RequestSpecification) {
  spec
    .`when`()
    .get("/users/123123123123123123121231")
    .then()
    .statusCode(404)
}</pre>



<p>This test will be also good proof that entries inserted to MongoDB in other tests do not affect other tests. </p>



<h3 class="wp-block-heading" id="h-extract-and-json-array-in-rest-assured">Extract and JSON Array in REST Assured</h3>



<p>Nextly, let&#8217;s take a look at the more complicated example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Test
fun `should create a user`(spec: RequestSpecification) {
  val request = AppUserRequest(
    firstName = "Piotr",
    lastName = "Wolak",
    email = "contact@codersee.com",
    street = "Street",
    city = "City",
    code = 123,
  )

  spec
    .`when`()
    .contentType(ContentType.JSON)
    .body(request)
    .post("/users")
    .then()
    .statusCode(201)

  val list = spec
    .`when`()
    .get("/users")
    .then()
    .statusCode(200)
    .body("size()", `is`(1))
    .extract()
    .`as`(object : TypeRef&lt;List&lt;AppUser>>() {})

  assertEquals(1, list.size)

  val createdUser = list.first()

  assertEquals(request.firstName, createdUser.firstName)
  assertEquals(request.street, createdUser.address.street)
}</pre>



<p>This time, we do a bunch of more interesting things. </p>



<p>Firstly, we make the <strong>POST request </strong>with a request body and <strong>verify that 201 Creates is returned</strong>. </p>



<p>After that, we call the <code>GET /users</code> endpoint to get a list of users. When we get the response, we <strong>verify that the JSON array size is equal to 1</strong> (with the <code>.body("size()", is(1))</code> call). Lastly, we <strong>make use of the extract().`as</strong>` to convert the payload into the List of AppUser instances. Thanks to that we can easily perform assertions with JUnit 5 functions. </p>



<h3 class="wp-block-heading" id="h-add-kotlin-utils-for-rest-assured">Add Kotlin Utils For REST Assured</h3>



<p>As you probably know, <code>when</code> and <code>as</code> are keywords in Kotlin and that&#8217;s why <strong>we had to use backticks (&#8220;)</strong>.</p>



<p>And to make our lives easier, let&#8217;s add the <code>util</code> package in <code>test</code> and create the <code>TestUtil.kt</code>: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import io.restassured.common.mapper.TypeRef
import io.restassured.response.ValidatableResponse
import io.restassured.specification.RequestSpecification


fun RequestSpecification.whenever(): RequestSpecification {
  return this.`when`()
}

fun &lt;T> ValidatableResponse.extractAs(clazz: Class&lt;T>) =
  this.extract()
    .`as`(clazz)

fun &lt;T> ValidatableResponse.extractAs(typeRef: TypeRef&lt;T>) =
  this.extract()
    .`as`(typeRef)</pre>



<p>As a result, from now on we can simply use the <em>whenever() </em>instead of <em>`when`()</em> and <em>extractAs() </em>instead of <em>extract().`</em>as`(). </p>



<h2 class="wp-block-heading" id="h-reference-the-server-context">Reference The Server / Context </h2>



<p>As the next step, let&#8217;s take a look at how to <strong>reference the server</strong> or <strong>current application context</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@MicronautTest
class InjectingExample{

  @Inject
  private lateinit var context: ApplicationContext

  @Inject
  private lateinit var server: EmbeddedServer

  // tests
}</pre>



<p>Sometimes it can be useful, and as we can see, we can simply inject them using the <strong>@Inject</strong> annotation. </p>



<h2 class="wp-block-heading" id="h-conditionally-run-tests">Conditionally Run Tests</h2>



<p>After that, let&#8217;s see <strong>how we can skip tests execution.</strong> </p>



<p>Why would we need that? </p>



<p>Well, integration tests sometimes can take a lot of time, and the bigger our project becomes, the bigger the chance they become annoying. And because of that, generally, it&#8217;s a good approach to somehow separate them from the faster unit tests. </p>



<p> When testing in Micronaut, we can easily achieve that using the <strong><em>@Requires</em></strong> annotation:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import io.micronaut.context.annotation.Requires
import io.micronaut.test.extensions.junit5.annotation.MicronautTest
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

@MicronautTest
@Requires(env = ["integration-test"])
class SomeIntegrationTest {

  @Test
  fun `should perform integration test`() {
    assertTrue(false)
  }

}</pre>



<p>The <strong><em>@MicronautTest</em></strong> annotation <strong>turns tests into beans</strong>. And that&#8217;s why we can use the <strong>@Requires</strong>, just like we would do with a &#8220;standard&#8221; bean.</p>



<p>As a result, tests inside the <code>SomeIntegrationTest</code> will run only, when the <code>integration-test</code> the environment is active. (And we can set that for example by setting the environment variable- <code>MICRONAUT_ENVIRONMENTS=integration-test</code>). </p>



<h2 class="wp-block-heading" id="h-testing-micronaut-with-mockk-mocks">Testing Micronaut With MockK Mocks</h2>



<p>As the last thing in our tutorial about testing Micronaut with Kotlin, let&#8217;s take a look at <strong>how we can mock things using the MockK</strong>.</p>



<p>Could we use Mockito? Yes. However, I find MockK better for Kotlin (DSLs &lt;3 ).</p>



<p>In order to mock a bean in Micronaut, the only thing we need to do is <strong>annotate the method/inner class with the @MockBean annotation</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@MicronautTest
class AppUserControllerTestWithMocking {

  private val repo: AppUserRepository = mockk&lt;AppUserRepository>()

  @MockBean(AppUserRepository::class)
  fun appUserRepository(): AppUserRepository = repo
}</pre>



<p>As we can see, we introduce the <code>AppUserRepository</code> mock as the <code>repo</code> property, so that later, we will be able to refer to it easily in our test cases. Additionally, we add the function annotated with <code>@MockBean</code>, thus informing Micronaut that the <code>AppUserRepository</code> is the type we want to replace with our mock. </p>



<p>Moreover, thanks to this approach <strong>this mock will be limited only to tests defined in this class</strong>. So we can &#8220;rest assured&#8221; (hue hue) it won&#8217;t interfere with other classes. </p>



<p>As a result, our tests will look, as follows: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@MicronautTest
class AppUserControllerTestWithMocking {

  private val repo: AppUserRepository = mockk&lt;AppUserRepository>()

  @Test
  fun `should return 200 OK on GET users`(spec: RequestSpecification) {
    every {
      repo.findAll()
    } returns emptyList()

    spec
      .whenever()
      .get("/users")
      .then()
      .statusCode(200)
      .header("Content-Type", "application/json")
  }

  @Test
  fun `should return user by ID`(spec: RequestSpecification) {
    val foundUser = AppUser(
      id = "123",
      firstName = "Piotr",
      lastName = "Wolak",
      email = "contact@codersee.com",
      address = Address(
        street = "street",
        city = "city",
        code = 123
      )
    )

    every {
      repo.findById("123")
    } returns Optional.of(foundUser)

    spec
      .whenever()
      .get("/users/123")
      .then()
      .statusCode(200)
      .body("id", equalTo("123"))
      .body("firstName", equalTo("Piotr"))
      .body("address.street", equalTo("street"))
      .body("address.code", equalTo(123))
  }

  @Test
  fun `should return user by ID and verify with extract`(spec: RequestSpecification) {
    val foundUser = AppUser(
      id = "123",
      firstName = "Piotr",
      lastName = "Wolak",
      email = "contact@codersee.com",
      address = Address(
        street = "street",
        city = "city",
        code = 123
      )
    )

    every {
      repo.findById("123")
    } returns Optional.of(foundUser)

    val extracted = spec
      .whenever()
      .get("/users/123")
      .then()
      .statusCode(200)
      .extractAs(AppUser::class.java)

    assertEquals(foundUser, extracted)
  }

  @Test
  fun `should create a user`(spec: RequestSpecification) {
    val request = AppUserRequest(
      firstName = "Piotr",
      lastName = "Wolak",
      email = "contact@codersee.com",
      street = "Street",
      city = "City",
      code = 123,
    )

    val createdUser = AppUser(
      id = "123",
      firstName = "Piotr",
      lastName = "Wolak",
      email = "contact@codersee.com",
      address = Address(
        street = "street",
        city = "city",
        code = 123
      )
    )

    every {
      repo.save(any())
    } returns createdUser

    val extracted = spec
      .whenever()
      .contentType(ContentType.JSON)
      .body(request)
      .post("/users")
      .then()
      .statusCode(201)
      .extractAs(AppUser::class.java)

    assertEquals(createdUser, extracted)
  }

  @MockBean(AppUserRepository::class)
  fun appUserRepository(): AppUserRepository = repo
}</pre>



<h2 class="wp-block-heading" id="h-summary">Summary</h2>



<p>And that&#8217;s all for this tutorial on <strong>how to perform testing in Micronaut with Kotlin.</strong></p>



<p>Together, we&#8217;ve discovered a bunch of interesting things that I hope will be useful in your projects. </p>



<p>If you would like to see the codebase for this tutorial, then check out <a href="https://github.com/codersee-blog/kotlin-micronaut-testing" target="_blank" rel="noreferrer noopener">this GitHub repository</a>. Or, if you are interested in learning more about Micronaut, then check out <a href="https://blog.codersee.com/category/micronaut/">my other posts</a>. </p>



<p>Let me know your thoughts in the comments section below! 🙂 </p>
<p>The post <a href="https://blog.codersee.com/testing-micronaut-appplication-kotlin/">Testing Micronaut Application in Kotlin</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/testing-micronaut-appplication-kotlin/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: blog.codersee.com @ 2026-05-13 23:13:07 by W3 Total Cache
-->