<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>webcodr</title>
    <link>https://webcodr.io/topics/kotlin/</link>
    <description>Recent content on webcodr</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 28 May 2025 20:22:07 +0200</lastBuildDate>
    <atom:link href="https://webcodr.io/topics/kotlin/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Please don&#39;t do this with switch statements</title>
      <link>https://webcodr.io/2025/05/please-dont-do-this-with-switch-statements/</link>
      <pubDate>Wed, 28 May 2025 20:22:07 +0200</pubDate>
      <guid>https://webcodr.io/2025/05/please-dont-do-this-with-switch-statements/</guid>
      <description>The classic C-like switch statement is fine, but it has its flaws. It’s no coincidence that modern languages like Kotlin or Rust offer alternatives like when or match or a more fine-tuned version of switch like Zig.
I’m currently in the early stages of rewriting a large and complex Java code base to Kotlin. Some parts of this codebase are really ugly and unnecessarily complicated and convoluted. Yesterday I crossed the path of a nasty use of a switch statement in an operation on a Java Stream. Unfortunately I can’t share the real code, but imagine something like this:
</description>
      <content:encoded><![CDATA[<p>The classic C-like switch statement is fine, but it has its flaws. It&rsquo;s no coincidence that modern languages like Kotlin or Rust offer alternatives like <code>when</code> or <code>match</code> or a more fine-tuned version of <code>switch</code> like Zig.</p>
<p>I&rsquo;m currently in the early stages of rewriting a large and complex Java code base to Kotlin. Some parts of this codebase are really ugly and unnecessarily complicated and convoluted. Yesterday I crossed the path of a nasty use of a switch statement in an operation on a Java Stream. Unfortunately I can&rsquo;t share the real code, but imagine something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kt">int</span><span class="w"> </span><span class="n">value1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">int</span><span class="w"> </span><span class="n">value2</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="p">(...)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="kd">enum</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="n">Enum</span><span class="p">.</span><span class="na">FOO</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">something</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">somethingElse</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">value1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">someConvolutedStreamOperations</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">value2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">someOtherConvolutedStreamOperations</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="c1">// imagine 30 more lines here</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">value2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">break</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="n">Enum</span><span class="p">.</span><span class="na">BAR</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">value1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">value2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">2</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">break</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>This was part of a Java class with over 1,000 lines of code. Streams with many operations everywhere and sometimes very deep nesting thanks to old-style Java code. The original case for <code>Enum.FOO</code> stretches over almost the whole display space, so it&rsquo;s not easy to spot any potential pitfalls. After I ran IntelliJ&rsquo;s Kotlin migration tool and cleaned up all errors, it was time to run the unit tests and four out of 24 failed.</p>
<p>As you can imagine it&rsquo;s not straight forward to find problems in such a large and complex class but I came across a notice of an unused value assignment. Why it was there was also not clear immediately, so I compared the original Java file with the Kotlin version.</p>
<p>Since Kotlin has no <code>switch</code> IntelliJ converted it to <code>when</code>. Unlike its Java counterpart <code>when</code> can handle <code>null</code> and is exhaustive with enums. There is also no <code>break</code> keyword and that&rsquo;s exactly the problem here.</p>
<p>Look at the Java code and think about what happens on <code>Enum.FOO</code> if <code>something</code> is true but <code>somethingElse</code> isn&rsquo;t. The <code>break</code> keyword is not triggered and the <code>switch</code> statement goes on to the default block. As a result <code>value1</code> and <code>value2</code> are assigned their values.</p>
<p>IntelliJ&rsquo;s migration tool is quite good, but it didn&rsquo;t catch that and the generated <code>when</code> statement was wrong. That&rsquo;s also the reason for the unused assignment notice. I assume the migration tool was confused by the scope of <code>break</code> since both <code>switch</code> and <code>for</code> can use it. Also there is no real match in Kotlin for such a structure. You have to assign the values of both variables for every branch inside the <code>when</code> statement. After fixing that all tests ran successfully.</p>
<p>It&rsquo;s a really good example of how not to use <code>switch</code> statements, especially with nested control structures in a case. Since the original author of the code is no longer available, I can only guess why it was written this way. Probably to avoid duplication or even unintended. Well, it could seem as an elegant solution if you&rsquo;re familiar with the code, but to other people it&rsquo;s just an unnecessary pitfall that should be avoided. It&rsquo;s unintuitive at best, not easy to comprehend and can lead to nasty bugs, especially if it&rsquo;s unintended behaviour. That&rsquo;s why Kotlin, Rust, Zig and other modern languages avoid breaks in their alternatives to switch statements in the first place.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Micro DSLs for builders with Kotlin</title>
      <link>https://webcodr.io/2024/01/micro-dsls-for-builders-with-kotlin/</link>
      <pubDate>Fri, 19 Jan 2024 14:33:07 +0200</pubDate>
      <guid>https://webcodr.io/2024/01/micro-dsls-for-builders-with-kotlin/</guid>
      <description>The builder pattern is a great tool and it’s heavily used in many Java projects and dependencies. But in a Kotlin code base it looks a little odd and out-of-date. In this short post I will show you how to write a micro DSL on top of a builder with just a few lines of code.
I’m using Spring’s ResponseCookie class as base for the DSL as it has a builder already on-board.
</description>
      <content:encoded><![CDATA[<p>The builder pattern is a great tool and it&rsquo;s heavily used in many Java projects and dependencies. But in a Kotlin code base it looks a little odd and out-of-date. In this short post I will show you how to write a micro DSL on top of a builder with just a few lines of code.</p>
<p>I&rsquo;m using Spring&rsquo;s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseCookie.html">ResponseCookie</a> class as base for the DSL as it has a builder already on-board.</p>
<p>A little example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="k">val</span> <span class="py">cookie</span> <span class="p">=</span> <span class="n">ResponseCookie</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">from</span><span class="p">(</span><span class="s2">&#34;cookie name&#34;</span><span class="p">,</span> <span class="s2">&#34;cookie value&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">httpOnly</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">path</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">build</span><span class="p">()</span>
</span></span></code></pre></div><p>What would this look like with a micro DSL?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="k">val</span> <span class="py">cookie</span> <span class="p">=</span> <span class="n">createCookie</span><span class="p">(</span><span class="s2">&#34;cookie name&#34;</span><span class="p">,</span> <span class="s2">&#34;cookie value&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">httpOnly</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">path</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Instead of calling the static method <code>ResponseCookie.from()</code> which returns a <code>ResponseCookieBuilder</code> object, you just give the function three parameters: two strings for name and value, and a trailing lambda with the builder context. There is also no need to call <code>ResponseCookieBuilder.build()</code> anymore. It&rsquo;s shorter and better to read. Since this is only a small example the advantages are not that big. Micro DSLs really shine with large and often used builders. They can also help to automate things, see below.</p>
<h2 id="how"><a href="#how" class="heading-anchor">How?</a></h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">createCookie</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">name</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">    <span class="k">value</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">    <span class="n">lambda</span><span class="p">:</span> <span class="nc">ResponseCookieBuilder</span><span class="p">.()</span> <span class="o">-&gt;</span> <span class="n">Unit</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="p">=</span> <span class="nc">ResponseCookie</span><span class="p">.</span><span class="n">from</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="k">value</span><span class="p">).</span><span class="n">apply</span><span class="p">(</span><span class="n">lambda</span><span class="p">).</span><span class="n">build</span><span class="p">()</span>
</span></span></code></pre></div><p>Et voila, a new micro DSL is born. Deriving the trailing lambda function from <code>ResponseCookieBuilder</code> does the trick. The lambda function takes an instance of <code>ResponseCookieBuilder</code> as context of <code>this</code>, so it&rsquo;s possible to access the methods of the given <code>ResponseCookieBuilder</code> inside the lambda function. All we have to do is to create an instance of <code>ResponseCookieBuilder</code> with <code>ResponseCookie.from()</code> and call Kotlin&rsquo;s apply method on the builder object with the lambda function. It will automatically inject the current instance of <code>ResponseCookieBuilder</code> into the lambda function and apply the instructions inside the lambda function on the instance. To create a <code>ResponseCookie</code> object from the builder, just call the build method and return the result.</p>
<p>You can use this little trick with all builders. Need more automation? No problem! In my current project we&rsquo;re using such micro DSLs to create product configurations. The factory method contains sanity checks after the lambda function was applied to the builder object. It will also fetch a YAML file via the product ID given to the builder. This data is parsed into an object and will be put into a property of the builder object. After the configuration object is created, the factory method will add it to a map and return the instance to store in a variable. It&rsquo;s now possible to directly access the configuration via its variable name or to fetch it from the map. The variable is very useful for tests, but if we have to fetch the configuration dynamically by ID from a string, the map is the way to go.</p>
<p>Of course there are other ways of achieving such automation, but the micro DSL approach is simple, improves readability and can also reduce redundant code. You can even easily nest builders to create a more powerful DSL. Spring&rsquo;s Kotlin extensions also rely on micro DSLs and extension functions. Take Spring Security for example. Their fluent interface for the security configuration is awful to read and difficult to understand, but Spring also provides a Kotlin extension with a micro DSL for that. So much more intuitive and better to read. There are many more extensions like for bean creation, the MVC mock in tests etc.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Kotest and JUnit with IntelliJ or: don’t frak up your toolchain upgrades</title>
      <link>https://webcodr.io/2020/08/kotest-and-junit-with-intellij-or-dont-frak-up-your-toolchain-upgrades/</link>
      <pubDate>Sat, 29 Aug 2020 22:26:07 +0200</pubDate>
      <guid>https://webcodr.io/2020/08/kotest-and-junit-with-intellij-or-dont-frak-up-your-toolchain-upgrades/</guid>
      <description>My team and I recently decided to use Kotlin for new features in our existing project. It was a great choice to implement a new authentication process and we’re now rewriting some older parts of the application from Java to Kotlin.
Actually I wanted to use Kotlin for a while now, but there were only minor tasks within the Java part of the project. That finally changed and we can focus to improve the Java backend drastically.
</description>
      <content:encoded><![CDATA[<p>My team and I recently decided to use Kotlin for new features in our existing project. It was a great choice to implement a new authentication process and we’re now rewriting some older parts of the application from Java to Kotlin.</p>
<p>Actually I wanted to use Kotlin for a while now, but there were only minor tasks within the Java part of the project. That finally changed and we can focus to improve the Java backend drastically.</p>
<p>Part of this process was a library update. We decided to upgrade JUnit from 4 to 5. A big pain in the ass. I don’t think, I would do it again. JUnit 5 was also part of a bigger problem, even if it was actually PEBKAC.</p>
<h2 id="kotest-and-mockk-features"><a href="#kotest-and-mockk-features" class="heading-anchor">Kotest and MockK features</a></h2>
<p>If you already know about Kotest or want to know more about the problem I had, just skip to the next headline. The Kotest introduction is a little bit longer.</p>
<p>As I dived more and more into Kotlin, I stumbled over Kotest. A really neat testing framework for Kotlin. There’s nothing wrong with JUnit, but Kotest gives you way more awesome ways to structure your tests.</p>
<p>A little example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kt" data-lang="kt"><span class="line"><span class="cl"><span class="k">package</span> <span class="nn">io.webcodr.demo</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.webcodr.demo</span>
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.kotest.assertions.throwables.shouldThrow</span>
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.kotest.core.spec.style.FunSpec</span>
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.mockk.*</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">UserServiceTest</span> <span class="p">:</span> <span class="n">FunSpec</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">val</span> <span class="py">userRepository</span> <span class="p">=</span> <span class="n">mockk</span><span class="p">&lt;</span><span class="n">UserRepository</span><span class="p">&gt;()</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">val</span> <span class="py">service</span> <span class="p">=</span> <span class="n">UserService</span><span class="p">(</span><span class="n">userRepository</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">lateinit</span> <span class="k">var</span> <span class="py">user</span><span class="p">:</span> <span class="n">User</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">init</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">beforeTest</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">user</span> <span class="p">=</span> <span class="n">User</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s2">&#34;Jane&#34;</span><span class="p">,</span> <span class="s2">&#34;Doe&#34;</span><span class="p">,</span> <span class="s2">&#34;jane@doe.com&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">afterTest</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">clearAllMocks</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">context</span><span class="p">(</span><span class="s2">&#34;getUser()&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">fun</span> <span class="nf">verifyRepoCalls</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">verify</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">userRepository</span><span class="p">.</span><span class="n">findById</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">confirmVerified</span><span class="p">(</span><span class="n">userRepository</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">test</span><span class="p">(</span><span class="s2">&#34;should succeed&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">every</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">userRepository</span><span class="p">.</span><span class="n">findById</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span> <span class="n">returns</span> <span class="n">user</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">service</span><span class="p">.</span><span class="n">getUser</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="n">shouldBe</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">verifyRepoCalls</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">test</span><span class="p">(</span><span class="s2">&#34;should fail&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">every</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">userRepository</span><span class="p">.</span><span class="n">findById</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span> <span class="n">throws</span> <span class="n">UserNotFoundException</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">shouldThrow</span><span class="p">&lt;</span><span class="n">UserNotFoundException</span><span class="p">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">service</span><span class="p">.</span><span class="n">getUser</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">verifyRepoCalls</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Kotest offers several different styles to write tests. I chose the <code>FunSpec</code> style for this example. You could also use a BDD-like or Jasmine-like style, if you want to.</p>
<p>It’s much more intuitive to nest tests with Kotest. To be fair, JUnit 5 allows you to use <code>@Nested</code> with an inner class to accomplish nesting as well, but it’s not as intuitive and harder to read than trailing lambdas.</p>
<p>Assertions are also a little easier to write. Kotest has over 100 different matchers. You can use them as extension functions, like in the example above or alternatively as infix functions, for example <code>service.getUser(1) shouldBe user</code>. It’s also quite simple to write custom matchers.</p>
<p>There are many more features like soft assertions, tagging, easy temporary file creation or handling for non-deterministic test cases.</p>
<p>For mocking we decided to use MockK, since it’s way more intuitive to use than Mockito with Kotlin. Don’t get me wrong, Mockito is a great library, but it has one flaw: the <code>when</code> method. <code>when</code> is a keyword in Kotlin and to use it with Mockito, you need to write it in backticks. That’s quite ugly and not intuitive at all.</p>
<p>So, in summary, Kotest offers a bunch of pretty neat features and is very intuitive to use. Of course, JUnit can achieve much of this as well, it’s just not that shiny and little harder to read.</p>
<h2 id="the-actual-problem-or-why-the-frak-is-there-intellij-in-the-title"><a href="#the-actual-problem-or-why-the-frak-is-there-intellij-in-the-title" class="heading-anchor">The actual problem or: why the frak is there IntelliJ in the title?</a></h2>
<p>If you migrate an old codebase to Kotlin and want to use Kotest, you will have no choice and have to use JUnit and Kotest in coexistence.</p>
<p>That shouldn’t be a problem, since Kotest uses the JUnit 5 Jupiter engine under the hood. But …</p>
<p>As I wrote a new service in Kotlin and some tests with Kotest, I could not start the JUnit tests anymore. As soon as the maven dependency of Kotest was present, IntelliJ didn’t recognize JUnit tests and used the Kotest files only. With <code>mvn test</code> (Maven Surefire) everything worked fine.</p>
<p>I tried several things and was ready to give up. Search engines didn’t find anything about this problem. Nothing on GitHub, nothing on Stack Overflow.</p>
<p>I hate to give up, so I decided to create a small demo project to open a GitHub issue. Well, that didn’t work out as intended, since the discovery of JUnit tests in the demo project worked fine. The IntelliJ JUnit runner did what it was supposed to: run JUnit and Kotest.</p>
<p>Well, frak. There must be some kind of configuration problem with my real project. I already looked at the IntelliJ runner config, Maven files etc. — nothing worked.</p>
<p>I compared the Maven files from both codebases and there was one difference: my real project did not include the JUnit Jupiter Engine dependency. Bingo. I added it to the Maven file and guess what? It worked like a charm.</p>
<p>What an embarrassment. As we upgraded from JUnit 4 to 5, we forgot to add the new dependency for the engine. I don’t know why the tests worked at all, but it seems the engine is not really necessary for all cases. But it can screw up test discovery quite well, if you forget it.</p>
<p>The dependency configuration in the POM file should look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;groupId&gt;</span>org.junit.jupiter<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;artifactId&gt;</span>junit-jupiter-api<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;version&gt;</span>${junit.version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;groupId&gt;</span>org.junit.jupiter<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;artifactId&gt;</span>junit-jupiter-engine<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;version&gt;</span>${junit.version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dependency&gt;</span>
</span></span></code></pre></div><p>Well, that was a long post, but IMO it was necessary to show how this problem came to be and even if you have no trouble at all, perhaps you’ll consider using Kotest. It’s awesome!</p>
<h2 id="gradle"><a href="#gradle" class="heading-anchor">Gradle</a></h2>
<p>I’m not sure, but this issue could happen with Gradle as well, when you are migrating to JUnit 5.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
