<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kotest</title>
    <description>The latest articles on DEV Community by Kotest (@kotest).</description>
    <link>https://dev.to/kotest</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2576%2F35bf4d7c-8e51-46f9-8260-1a1e94943878.png</url>
      <title>DEV Community: Kotest</title>
      <link>https://dev.to/kotest</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kotest"/>
    <language>en</language>
    <item>
      <title>Kotest Release 4.3</title>
      <dc:creator>Stephen Samuel</dc:creator>
      <pubDate>Sun, 11 Oct 2020 19:44:47 +0000</pubDate>
      <link>https://dev.to/kotest/kotest-release-4-3-2768</link>
      <guid>https://dev.to/kotest/kotest-release-4-3-2768</guid>
      <description>&lt;p&gt;The Kotest team is pleased to announce the release of Kotest 4.3.0.&lt;/p&gt;

&lt;p&gt;This blog covers some of the new features added in this release.&lt;br&gt;
For the full list, see the &lt;a href="https://kotest.io/changelog/" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  New and improved data driven testing
&lt;/h2&gt;

&lt;p&gt;Kotest has improved its data driven testing support, directly integrating into the framework. This means it will now automatically generate individual test case entries.&lt;/p&gt;

&lt;p&gt;As an example, lets test a function that returns true if the input values are valid &lt;a href="https://en.wikipedia.org/wiki/Pythagorean_triple" rel="noopener noreferrer"&gt;pythagorean triples&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isPythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start by writing a data class that will hold each &lt;em&gt;row&lt;/em&gt; - a set of inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we invoke the function &lt;code&gt;forAll&lt;/code&gt; inside a test case, passing in one or more of these data classes, and a&lt;br&gt;
lambda that performs some test logic for a given &lt;em&gt;row&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pythag triples tests"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;forAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="nc"&gt;PythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="nc"&gt;PythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="nc"&gt;PythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="nc"&gt;PythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;isPythagTriple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotest will automatically generate a test case for each input row, as if you had manually written a seperate test case for each.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fkotest%2Fkotest%2Fmaster%2Fdocs%2Fimages%2Fdatatest1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fkotest%2Fkotest%2Fmaster%2Fdocs%2Fimages%2Fdatatest1.png" alt="data test example output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For full documentation &lt;a href="https://kotest.io/data_driven_testing/" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  EnabledIf annotation on specs
&lt;/h2&gt;

&lt;p&gt;It can be useful to avoid instantiating a spec entirely, and often we can do that via test tags. But if you want to do this with some bespoke code, then the annotation &lt;code&gt;EnabledIf&lt;/code&gt; has been added.&lt;/p&gt;

&lt;p&gt;Annotate a spec with &lt;code&gt;EnabledIf&lt;/code&gt;, passing in a class that extends from &lt;code&gt;EnabledCondition&lt;/code&gt; and that condition will be invoked at runtime to determine if the spec should be instantiated. The &lt;code&gt;EnabledCondition&lt;/code&gt; implementation must have a zero arg constructor.&lt;/p&gt;

&lt;p&gt;For example, lets make a condition that only executes a test if it is midnight.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EnabledIfMidnight&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;EnabledCondition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;specKlass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;KClass&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="nc"&gt;Spec&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LocalTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then attach that to a spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@EnabledIf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EnabledIfMidnight&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EnabledIfTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tis midnight when the witches roam free"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// test here&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  TestCase severity
&lt;/h2&gt;

&lt;p&gt;Test case can be conditionally executed via test tags, and now also by severity levels. The levels are BLOCKER, CRITICAL, NORMAL, MINOR, and TRIVIAL.&lt;/p&gt;

&lt;p&gt;We can mark each test case with a severity level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"very very important"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;severity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TestCaseSeverityLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CRITICAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// test here&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Say we only want to execute tests that are CRITICAL or higher, we can execute with the system property &lt;code&gt;kotest.framework.test.severity=CRITICAL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This can be useful if we have a huge test suite and want to run some tests first in a seperate test run.&lt;/p&gt;

&lt;p&gt;By default, all tests are executed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disabling source references
&lt;/h2&gt;

&lt;p&gt;Whenever a test case is created, Kotest creates a stack trace so that it can link back to the test case. The stack trace contains the filename and line number which the Intellij Plugin uses to create links in the test window. It calls these the &lt;em&gt;sourceref&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you have 1000s of tests and are encountering some slowdown when executing the full suite via gradle, you can now disable&lt;br&gt;
the generation of these sourcerefs by setting the system property &lt;code&gt;kotest.framework.sourceref.disable=true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generally speaking, this is only of use if you have a huge test suite and mostly aimed at CI builds.&lt;/p&gt;
&lt;h2&gt;
  
  
  Make engine dependency free
&lt;/h2&gt;

&lt;p&gt;A test framework is one of the lowest levels of dependences in an ecosystem. As Kotest is used by many Kotlin libraries, a clash can occur if Kotest and your project are using the same dependencies but with different versions.&lt;/p&gt;

&lt;p&gt;It is beneficial then if Kotest has as few dependencies as possible. To this aim, 4.3.0 has seen the dependencies for the Kotest framework reduced to just Classgraph (to scan for specs), Mordant (for console output), and opentest4j.&lt;/p&gt;
&lt;h2&gt;
  
  
  Matchers return 'this' for easy chaining
&lt;/h2&gt;

&lt;p&gt;In the opinion of this author, Kotest has the most comprehensive assertion support for Kotlin. Now they just became more convienient, by allowing you to chain assertions together if you wish.&lt;/p&gt;

&lt;p&gt;So, instead of&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBeSorted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldHaveSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldContain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Chicago"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBeSorted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldHaveSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldContain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Chicago"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, this is entirely optional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Property test module for kotlinx datetime
&lt;/h2&gt;

&lt;p&gt;Kotest's expansive property test library now includes generators for the incubating &lt;a href="https://github.com/Kotlin/kotlinx-datetime" rel="noopener noreferrer"&gt;kotlinx datetime library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add the module &lt;code&gt;kotest-property-datetime&lt;/code&gt; to your build. These generators are available for JVM and JS.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;forAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1987&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;1994&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class="nf"&gt;isValidStarTrekTngSeason&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Option to strip whitespace from test names
&lt;/h2&gt;

&lt;p&gt;If you like to define test names over multiple lines, Kotest will now strip out leading, trailing and repeated whitespace from test names.&lt;/p&gt;

&lt;p&gt;For example, the following spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySpec&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;StringSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s"&gt;"""this is a
      test spanning multiple lines"""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Would normally be output as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this is a      test spanning multiple lines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By setting the configuration object &lt;code&gt;removeTestNameWhitespace&lt;/code&gt; to true, this would instead by output as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this is a test spanning multiple lines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Huge thanks to all who contributed to this release:&lt;/p&gt;

&lt;p&gt;AJ Alt, Alex Facciorusso, Ashish Kumar Joy, J Phani Mahesh, Jasper de Vries, Javier Segovia Córdoba,&lt;br&gt;
Josh Graham, KeremAslan, Leonardo Colman, Michał Sikora, Mitchell Yuwono, Neenad Ingole, Rick Busarow,&lt;br&gt;
SergKhram, Sergei Khramkov, crazyk2, sksamuel&lt;/p&gt;

</description>
      <category>testing</category>
      <category>kotlin</category>
      <category>kotest</category>
    </item>
    <item>
      <title>Testing Kotlin/JS with Kotest</title>
      <dc:creator>Stephen Samuel</dc:creator>
      <pubDate>Sun, 20 Sep 2020 19:17:03 +0000</pubDate>
      <link>https://dev.to/kotest/testing-kotlin-js-with-kotest-i2j</link>
      <guid>https://dev.to/kotest/testing-kotlin-js-with-kotest-i2j</guid>
      <description>&lt;p&gt;One of the areas Kotlin has focused on in recent releases is with multi-platform support. Kotlin code, the Kotlin standard library and other supported dependencies can be compiled into ES5 Javascript.&lt;/p&gt;

&lt;p&gt;When targeting platforms that are not JVM based, our options for testing are reduced. The two best known Java testing frameworks (JUnit and TestNG) are JVM specific and won't work when we compile to Javascript. Instead, in this short article I will show how it is possible to use &lt;a href="https://kotest.io/" rel="noopener noreferrer"&gt;Kotest&lt;/a&gt; to test against Kotlin/JS.&lt;/p&gt;

&lt;p&gt;Firstly, I will assume you already have a project setup with javascript support. If not, then &lt;a href="https://kotlinlang.org/docs/reference/js-overview.html" rel="noopener noreferrer"&gt;follow this guide&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This means you will end up a structure that contains a &lt;code&gt;main&lt;/code&gt; source folder and a &lt;code&gt;test&lt;/code&gt; sources folder as is usual, with the koltin-js standard library added.&lt;/p&gt;

&lt;p&gt;Let's add a basic Javascript function that validates &lt;a href="https://www.ssa.gov/ssnumber/" rel="noopener noreferrer"&gt;US social security numbers&lt;/a&gt;. This will be the function that we want to test with Kotest. &lt;/p&gt;

&lt;p&gt;Inside the source root, we create a file called &lt;code&gt;ssn.kt&lt;/code&gt; that contains the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlin.js.RegExp&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;socialRegex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^\\d{3}-\\d{2}-\\d{4}$"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;socialRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ssn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ssn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"666"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll notice we are using the &lt;code&gt;kotlin.js.RegExp&lt;/code&gt; class. This is a Kotlin wrapper around the built in Javascript regular expression support. This is one of the nice touches about Kotlin's multi-platform support - it allows you to use platform specific functions, rather than going down lowest common denominator path of only allowing functions that work on all platforms.&lt;/p&gt;

&lt;p&gt;There are some &lt;a href="https://www.lexjansen.com/nesug/nesug07/ap/ap19.pdf" rel="noopener noreferrer"&gt;basic rules&lt;/a&gt; when it comes to validating SSN numbers. The general format is a 3 digit area code, a 2 digit group code, and a 4 digit serial number. Our function requires hyphens between these sets of numbers.&lt;/p&gt;

&lt;p&gt;Additionally, no number can be zero, and 666 is not valid as an area code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the build for Kotest
&lt;/h2&gt;

&lt;p&gt;To begin testing, we need to add the appropriate Kotest dependencies. These are &lt;code&gt;kotest-framework-engine-js&lt;/code&gt; and &lt;code&gt;kotest-framework-api-js&lt;/code&gt; for the test framework, and &lt;code&gt;kotest-assertions-core-js&lt;/code&gt; for the assertions library. Note that the assertions library is optional, in case you want to use assertions from another library.&lt;/p&gt;

&lt;p&gt;If you are not using coroutines already, you will need to bring in the &lt;code&gt;kotlinx-coroutines-core-js&lt;/code&gt; dependency in as well. &lt;/p&gt;

&lt;p&gt;So, your build file should contain something similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;kotlin&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

   &lt;span class="n"&gt;js&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;sourceSets&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.3.9'&lt;/span&gt;
            &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.kotest:kotest-assertions-core-js:4.2.5'&lt;/span&gt;
            &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.kotest:kotest-framework-api-js:4.2.5'&lt;/span&gt;
            &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.kotest:kotest-framework-engine-js:4.2.5'&lt;/span&gt;
         &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Writing a Test
&lt;/h2&gt;

&lt;p&gt;To begin writing our tests, we create a &lt;code&gt;Spec&lt;/code&gt;. A spec is the name Kotest uses for a class that contains test definitions. These are just regular classes that extend one of the Kotest &lt;a href="https://kotest.io/styles/" rel="noopener noreferrer"&gt;spec styles&lt;/a&gt;. For Javascript we must choose one of the simpler specs - &lt;code&gt;FunSpec&lt;/code&gt; in this case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.core.spec.style.FunSpec&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.matchers.shouldBe&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SsnTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a SSN should be invalid when it contains a zero in any position"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"543-23-5013"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"043-23-5313"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"313-03-5310"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nested inside the constructor lambda block is our first test case. We check that if a zero appears inside the SSN then it is not valid.&lt;/p&gt;

&lt;p&gt;Executing this test is just a matter of invoking the gradle &lt;code&gt;test&lt;/code&gt; task, either at the command line, or from within intelliJ. The Kotlin/JS plugin for gradle will take care of downloading Mocha and/or Karma depending on whether the project is Browser and/or NodeJS based.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imgur.com/U5qUV8r.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FU5qUV8r.png" alt="https://imgur.com/U5qUV8r.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, if all goes well, you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imgur.com/z9ocTC3.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2Fz9ocTC3.png" alt="https://imgur.com/z9ocTC3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's round out our test suite, by adding tests to confirm the 666 rule, and that inputs must be in the required 3-2-4 format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.core.spec.style.FunSpec&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.matchers.shouldBe&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SsnTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a SSN should be invalid when it contains a zero in any position"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"543-23-5013"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"043-23-5313"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"313-03-5310"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a SSN should be invalid when it starts with 666"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"666-23-1234"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a SSN should be in the required format"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"123-45-6789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"123-45-678"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"12-45-6789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1234-56-678"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"123456789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"123-456789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"12345-6789"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
      &lt;span class="nf"&gt;validateSocial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://imgur.com/aWeItVd.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FaWeItVd.png" alt="https://imgur.com/aWeItVd.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Coroutines and Promises
&lt;/h2&gt;

&lt;p&gt;The interop of Kotest and Javascript doesn't stop there. Every test in Kotest is executed inside of a coroutine, so we can test suspend functions directly. Internally these are mapped to Javascript Promises.&lt;/p&gt;

&lt;p&gt;We're going to test a function that uses the Ktor HTTP client to connect to a public API to fetch a &lt;a href="https://dog.ceo/api/breeds/image/random" rel="noopener noreferrer"&gt;picture of a dog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://images.dog.ceo/breeds/leonberg/n02111129_844.jpg" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.dog.ceo%2Fbreeds%2Fleonberg%2Fn02111129_844.jpg" alt="https://images.dog.ceo/breeds/leonberg/n02111129_844.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, add &lt;code&gt;implementation 'io.ktor:ktor-client-js:1.4.0'&lt;/code&gt; to your main source. Then create a new file called &lt;code&gt;http.kt&lt;/code&gt; which contains the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.client.HttpClient&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.client.engine.js.Js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.client.request.get&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.client.statement.HttpResponse&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.client.statement.readText&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;resp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://dog.ceo/api/breeds/image/random"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;fetch&lt;/code&gt; function invokes the API, returning an instance of &lt;code&gt;Dog&lt;/code&gt;, parsed from the returned Json. Notice the use of the &lt;code&gt;JSON.parse&lt;/code&gt; function which is part of the Kotlin/JS std library. There is no error handling here since this is just a simple example of suspendable functions in action.&lt;/p&gt;

&lt;p&gt;The next part is of course to write the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.core.spec.style.FunSpec&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.matchers.string.shouldEndWith&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fetching a dog using JS promises"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldEndWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".jpg"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, testing a suspend function is as easy as testing the &lt;code&gt;validateSocial&lt;/code&gt; function from earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imgur.com/rbvKRu2.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FrbvKRu2.png" alt="https://imgur.com/rbvKRu2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And just to prove that the test is indeed waiting for the response to complete, we can add an incorrect assertion to see the test fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.core.spec.style.FunSpec&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotest.matchers.string.shouldEndWith&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fetching a dog using JS promises"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldEndWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".jpg2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://imgur.com/A3D1DBH.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FA3D1DBH.png" alt="https://imgur.com/A3D1DBH.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imgur.com/JL05cIe.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FJL05cIe.png" alt="https://imgur.com/JL05cIe.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's how simple it is to use Kotest for Javascript tests. Kotlin/Javascript interop is still somewhat new and so there are some restrictions that you may run across.&lt;/p&gt;

&lt;p&gt;The full project can be found &lt;a href="https://github.com/kotest/kotest-examples-javascript" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>testing</category>
      <category>javascript</category>
      <category>kotest</category>
    </item>
    <item>
      <title>Writing reusable tests with Kotest's Test Factory</title>
      <dc:creator>Leonardo Colman Lopes</dc:creator>
      <pubDate>Thu, 16 Apr 2020 20:02:59 +0000</pubDate>
      <link>https://dev.to/kotest/writing-reusable-tests-with-kotest-s-test-factory-5gi</link>
      <guid>https://dev.to/kotest/writing-reusable-tests-with-kotest-s-test-factory-5gi</guid>
      <description>&lt;p&gt;TL;DR - How to use &lt;a href="https://github.com/kotest/kotest" rel="noopener noreferrer"&gt;Kotest&lt;/a&gt; 4.0.0 new Test Factory feature to include reusable blocks of test in your test suite&lt;/p&gt;

&lt;h1&gt;
  
  
  Hello, Kotliners!
&lt;/h1&gt;

&lt;p&gt;In this article we'll see how to use a feature from the &lt;a href="https://github.com/kotest/kotest" rel="noopener noreferrer"&gt;Kotest Framework&lt;/a&gt; to create reusable tests in your test suite, for cases in which you test multiple classes exactly the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declaring a Test Factory function
&lt;/h2&gt;

&lt;p&gt;It's very easy to create a reusable test. You must first pick your favourite style among &lt;a href="https://github.com/kotest/kotest/blob/master/doc/styles.md" rel="noopener noreferrer"&gt;Kotest's test styles&lt;/a&gt;. You can pick any of them, but my personal favourite (and the one I'll use here) is &lt;code&gt;FunSpec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Declaring a test using &lt;code&gt;FunSpec&lt;/code&gt; is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySpec&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Foo should not be equal to bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"foo"&lt;/span&gt; &lt;span class="n"&gt;shouldNotBe&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Declaring the same test, but this time as a test factory is very similar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Top level val&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myReusableTest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;funSpec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Foo should not be equal to bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"foo"&lt;/span&gt; &lt;span class="n"&gt;shouldNotBe&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, there are some cases in which having the same test will produce a different result if called multiple times. For cases which our tests depend on some parameters, we might rather want to use use this as a function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;myReusableTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myParameter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;funSpec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$myParameter should not be equal to bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;myParameter&lt;/span&gt; &lt;span class="n"&gt;shouldNotBe&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both cases can be included in any &lt;code&gt;Spec&lt;/code&gt; by using the &lt;code&gt;include&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My usual test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;myReusableTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;myReusableTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Another usual test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as expected, the tests from the test factory are applied!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstp0ysvjghtk8ayy4vbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstp0ysvjghtk8ayy4vbw.png" width="398" height="197"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  A small example
&lt;/h2&gt;

&lt;p&gt;Now that we understand the basic concept, let's play a little bit with a more realistic example: Calculators! &lt;del&gt;really realistic, everyone implements calculators&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;Let's suppose we have 3 types of calculators:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Sum Calculator&lt;/li&gt;
&lt;li&gt;A Subtraction Calculator&lt;/li&gt;
&lt;li&gt;A Complete Calculator, that can do both operations.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;SumOp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;SumCalculator&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SumOp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;SubtractionOp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;SubtractionCalculator&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SubtractionOp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To test these implementations, we would create a &lt;code&gt;Spec&lt;/code&gt; for each:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SumCalculatorTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum 2 and 2 should be 4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SumCalculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SubtractionCalculatorTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"4 minus 2 should be 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SubtractionCalculatorTest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When implementing our &lt;code&gt;CompleteCalculator&lt;/code&gt;, we should test these behaviours as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;CompleteCalculator&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SumOp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SubtractionOp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompleteCalculatorTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum 2 and 2 should be 4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;CompleteCalculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"4 minus 2 should be 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;CompleteCalculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have ended up writing the same test that we already wrote for sum calc and sub calc. This is duplication that we'd like to try and avoid.&lt;/p&gt;

&lt;p&gt;Now let's exercise what we learned previously. Writing tests through composition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;sumTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SumOp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;funSpec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum 2 and 2 should be 4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;subtractionTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SubtractionOp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;funSpec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"4 minus 2 should be 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SumCalculatorTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sumTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SumCalculator&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SubtractionCalculatorTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;subtractionTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SubtractionCalculator&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompleteCalculatorTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sumTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CompleteCalculator&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;subtractionTests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CompleteCalculator&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;em&gt;voilà!&lt;/em&gt; We successfully reused a test for more than one scenario!&lt;/p&gt;

&lt;h2&gt;
  
  
  What could this be useful for?
&lt;/h2&gt;

&lt;p&gt;In the real world we won't be implementing calculators as often as we want to. So, &lt;strong&gt;why would I use this kind of factory and composition&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;We created these &lt;strong&gt;Test Factories&lt;/strong&gt; for any kind of repeatable test pattern. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you need to test that every &lt;code&gt;Repository&amp;lt;MyEntity&amp;gt;&lt;/code&gt; creates a database entity with a new ID&lt;/li&gt;
&lt;li&gt;If your &lt;code&gt;cache&lt;/code&gt; and your actual database return data in the same format&lt;/li&gt;
&lt;li&gt;If sending a &lt;code&gt;POST&lt;/code&gt; request to some endpoint always returns the payload in a specific format&lt;/li&gt;
&lt;li&gt;If all instances of a &lt;code&gt;sealed class&lt;/code&gt; have their class' name on the &lt;code&gt;toString&lt;/code&gt; function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And much more scenarios that you might be exploring with!&lt;/p&gt;

</description>
      <category>kotest</category>
      <category>kotlin</category>
      <category>testing</category>
    </item>
    <item>
      <title>Testing Koin applications with Kotest</title>
      <dc:creator>Leonardo Colman Lopes</dc:creator>
      <pubDate>Mon, 22 Jul 2019 15:09:16 +0000</pubDate>
      <link>https://dev.to/kotest/testing-koin-applications-with-kotlintest-1iip</link>
      <guid>https://dev.to/kotest/testing-koin-applications-with-kotlintest-1iip</guid>
      <description>&lt;p&gt;TL;DR - Using the &lt;code&gt;KoinListener&lt;/code&gt; from &lt;a href="https://github.com/kotest/kotest" rel="noopener noreferrer"&gt;Kotest&lt;/a&gt; to write tests that depend on &lt;a href="https://insert-koin.io/" rel="noopener noreferrer"&gt;Koin&lt;/a&gt; modules in a Kotest Spec&lt;/p&gt;

&lt;h1&gt;
  
  
  Hello, Kotliners!
&lt;/h1&gt;

&lt;p&gt;In this article we will see how to test applications that use the &lt;a href="https://insert-koin.io/" rel="noopener noreferrer"&gt;Koin DI Framework&lt;/a&gt; in a &lt;code&gt;Spec&lt;/code&gt; from the &lt;a href="https://github.com/kotest/kotest" rel="noopener noreferrer"&gt;Kotest&lt;/a&gt; Framework. We'll take the JUnit example from Koin's documentation and enhance it with Kotest.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 simple steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add Kotest's Koin extensions to your build.gradle&lt;/li&gt;
&lt;li&gt;Transform your JUnit test into a Kotest Spec (or create one from scratch)&lt;/li&gt;
&lt;li&gt;Add the KoinListener to your class&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Add Koin extension to your build.gradle
&lt;/h2&gt;

&lt;p&gt;On your &lt;code&gt;build.gradle&lt;/code&gt; file we'll add the Koin Extension dependency as a &lt;code&gt;testImplementation&lt;/code&gt;. I'm assuming you already have Kotest configured. If you don't, &lt;a href="https://github.com/kotest/kotest#use" rel="noopener noreferrer"&gt;take a look at the docs&lt;/a&gt; on how to do it.&lt;/p&gt;




&lt;p&gt;I like to keep the Koin Extension definition close to my Kotest definition&lt;/p&gt;

&lt;p&gt;build.gradle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    // ... Your dependencies ... 

    // Kotest
    testImplementation("io.kotest:kotest-runner-junit5:{version}")
    testImplementation("io.kotest:kotest-extensions-koin:{version}")

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Transform a JUnit test to a Kotest Spec
&lt;/h2&gt;

&lt;p&gt;For this example, we are going to use the &lt;a href="https://insert-koin.io/docs/2.0/quick-references/testing-your-components/" rel="noopener noreferrer"&gt;JUnit example from the Koin docs&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyTest : KoinTest {

    // Lazy inject property
    val componentA : ComponentA by inject()

    // use it in your tests :)
    @Test
    fun `make a test with Koin`() {
        startKoin { modules(appModule) }

        // use componentA here!
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Converting the test
&lt;/h3&gt;

&lt;p&gt;There are a &lt;a href="https://github.com/Kotest/Kotest/blob/master/doc/styles.md" rel="noopener noreferrer"&gt;lot of styles&lt;/a&gt; that can be used in Kotest, let's try with &lt;code&gt;FunSpec&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyTest : FunSpec(), KoinTest {


    // Lazy inject property
    val componentA : ComponentA by inject()

    init {
        test("Make a test with Koin") {
            startKoin { modules(appModule) }

            // use componentA here!
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will already work! &lt;/p&gt;

&lt;p&gt;This example works in the same way as the JUnit code. If we add more tests to the class, we'll have to clear Koin's context. In JUnit we create a &lt;code&gt;@After&lt;/code&gt; method. Let's see how to do this in Kotest&lt;/p&gt;




&lt;h2&gt;
  
  
  Add KoinListener to the class
&lt;/h2&gt;

&lt;p&gt;To fix this, we can either override the &lt;code&gt;afterTest&lt;/code&gt; function, that works similarly to &lt;code&gt;@After&lt;/code&gt; or we can use the &lt;code&gt;KoinListener&lt;/code&gt; to do that automatically for us! Let's try with that approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyTest : FunSpec(), KoinTest {

    override fun listeners() = listOf(KoinListener(appModule))

    // Lazy inject property
    val componentA : ComponentA by inject()

    init {
        test("Make a test with Koin") {

            // use componentA here!
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;KoinListener&lt;/code&gt; we will have Kotest handle both Koin's start (see that we removed that line in our test!) and Koin's stop.&lt;/p&gt;

&lt;h3&gt;
  
  
  And that's it!
&lt;/h3&gt;

&lt;p&gt;With this simple setup, you'll be able to test your Koin Application with Kotest, and use all the available features from both of them!&lt;/p&gt;

&lt;p&gt;If you still have any doubt, check out the &lt;a href="https://github.com/Kotest/Kotest/blob/master/doc/extensions.md#koin" rel="noopener noreferrer"&gt;full documentation&lt;/a&gt; on &lt;code&gt;KoinListener&lt;/code&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kotest</category>
      <category>testing</category>
      <category>koin</category>
    </item>
    <item>
      <title>Testing System Properties and System Environment with Kotest</title>
      <dc:creator>Leonardo Colman Lopes</dc:creator>
      <pubDate>Sun, 21 Jul 2019 21:16:50 +0000</pubDate>
      <link>https://dev.to/kotest/testing-system-properties-and-system-environment-with-kotlintest-3cnb</link>
      <guid>https://dev.to/kotest/testing-system-properties-and-system-environment-with-kotlintest-3cnb</guid>
      <description>&lt;p&gt;TL;DR: Test code that uses &lt;code&gt;System.getenv()&lt;/code&gt; or &lt;code&gt;System.getProperty()&lt;/code&gt; with easy-to-use functions with &lt;a href="https://github.com/Kotest/Kotest" rel="noopener noreferrer"&gt;Kotest&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Hello Kotliners!
&lt;/h1&gt;

&lt;p&gt;In this article we'll discuss a little bit two features of Kotest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System Environment extensions&lt;/li&gt;
&lt;li&gt;System Property extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They're very similar on their implementation and use, and are very easy to use!&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;In the JVM world, some (many) times our code depends on what the system provides us, usually through &lt;em&gt;Environment Variables&lt;/em&gt; or &lt;em&gt;Properties&lt;/em&gt; passed to the JVM.&lt;/p&gt;

&lt;p&gt;However, neither is very easy to test when we want to use it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;System.getenv()&lt;/code&gt; map &lt;a href="http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/solaris/classes/java/lang/ProcessEnvironment.java#l78" rel="noopener noreferrer"&gt;is immutable&lt;/a&gt;. We can't set it up using plain Java&lt;/li&gt;
&lt;li&gt;Messing with &lt;code&gt;System.setProperty()&lt;/code&gt; manually forces us to do all the setup and tear-down, and becomes very verbose and cumbersome&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://unsplash.com/@vheath" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FtaONeg2.jpg" width="800" height="333"&gt;&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Photo by &lt;a href="https://unsplash.com/@vheath?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Victoria Heath&lt;/a&gt; on Unsplash&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Kotest provides some extensions and listeners to handle these scenarios. The complete documentation can be found &lt;a href="https://github.com/Kotest/Kotest/blob/master/doc/extensions.md#system-extensions" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  System Environment Extensions
&lt;/h3&gt;

&lt;p&gt;If the piece of code under test is small enough and used only once, we can use the &lt;code&gt;withSystemEnvironment&lt;/code&gt;. It has overloads, but we'll use the &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt; one. There's an overload expecting a &lt;code&gt;Pair&amp;lt;K,V&amp;gt;&lt;/code&gt; and one expecting a &lt;code&gt;Map&amp;lt;K,V&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EnvironmentTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Changing environment"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;withSystemEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"barValue"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKey"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"barValue"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  System Properties Extensions
&lt;/h3&gt;

&lt;p&gt;In the same fashion as above, we have the function &lt;code&gt;withSystemProperties&lt;/code&gt;, that works very similarly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PropertyTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Changing System Properties"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;withSystemProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKey"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"barValue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"booKey"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"batValue"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKey"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"barValue"&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"booKey"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"batValue"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cleanup
&lt;/h3&gt;

&lt;p&gt;After the execution, the previous values will be set to what they were before. What is already in the map will remain untouched during the execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Listeners
&lt;/h3&gt;

&lt;p&gt;Perhaps your code require the specific properties in every test. You can configure the &lt;code&gt;SystemPropertyTestListener&lt;/code&gt; and the &lt;code&gt;SystemEnvironmentTestListener&lt;/code&gt; for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SystemEnvironmentTestListenerTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;SystemEnvironmentTestListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKeyEnv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"barValueEnv"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nc"&gt;SystemPropertyTestListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKeyProp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"barValueProp"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"System Property"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKeyProp"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"barValueProp"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"System Environment"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fooKeyEnv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"barValueEnv"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The original values will reset after the test execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Listener
&lt;/h3&gt;

&lt;p&gt;You can also set these globally by using the &lt;code&gt;SystemEnvironmentProjectListener&lt;/code&gt; and the &lt;code&gt;SystemPropertyProjectListener&lt;/code&gt;. More information on Project Configuration can be found in &lt;a href="https://github.com/Kotest/Kotest/blob/master/doc/reference.md#project-config" rel="noopener noreferrer"&gt;Kotest's Docs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProjectConfig&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AbstractProjectConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TestListener&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SystemEnvironmentProjectListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Override Mode
&lt;/h3&gt;

&lt;p&gt;All the above extensions accept a parameter of the enum &lt;code&gt;OverrideMode&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SetOrOverride - If the key we want to set is already in the properties/environment, we want to override it for the test&lt;/li&gt;
&lt;li&gt;SetOrIgnore - If the key is already present, we'll not override it and the test will continue&lt;/li&gt;
&lt;li&gt;SetOrError (default) - If the key is already present, interrupt the test with an Exception&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are very useful if you need to use, for example, a property in the global listener, but want to override it in a specific test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;withSystemProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;OverrideMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetOrOverride&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// foo is overrided here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Extensions in action
&lt;/h3&gt;

&lt;p&gt;I've published 2 small and simple libs that exercise these listeners and extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Kerooker/SimpleProperties" rel="noopener noreferrer"&gt;SimpleProperties&lt;/a&gt; - That reads values both from Environment and Properties. &lt;a href="https://github.com/Kerooker/SimpleProperties/blob/master/src/test/kotlin/com/kerooker/simpleproperties/internal/profile/SystemProfileLoaderTest.kt" rel="noopener noreferrer"&gt;Test Class&lt;/a&gt;. It's even possible to see both extensions &lt;a href="https://github.com/Kerooker/SimpleProperties/blob/a5650444029050a80f5fdc6128a45f73f8a299b6/src/test/kotlin/com/kerooker/simpleproperties/internal/profile/SystemProfileLoaderTest.kt#L53" rel="noopener noreferrer"&gt;used at once&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Kerooker/SimpleFeatureThrottler" rel="noopener noreferrer"&gt;SimpleFeatureThrottler&lt;/a&gt; - A similar approach can be seen in &lt;a href="https://github.com/Kerooker/SimpleFeatureThrottler/blob/master/src/test/kotlin/com/kerooker/simplefeaturethrottler/internal/SystemPercentageFetcherTest.kt" rel="noopener noreferrer"&gt;this test class&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kotlin</category>
      <category>kotest</category>
      <category>testing</category>
    </item>
    <item>
      <title>Testing a Spring Boot application with Kotest</title>
      <dc:creator>Leonardo Colman Lopes</dc:creator>
      <pubDate>Thu, 11 Jul 2019 03:49:44 +0000</pubDate>
      <link>https://dev.to/kotest/testing-a-spring-boot-application-with-kotlintest-pgd</link>
      <guid>https://dev.to/kotest/testing-a-spring-boot-application-with-kotlintest-pgd</guid>
      <description>&lt;p&gt;TL;DR - How to use the SpringListener from &lt;a href="https://github.com/Kotest/Kotest" rel="noopener noreferrer"&gt;Kotest&lt;/a&gt; to test Spring Boot applications, including some samples&lt;/p&gt;

&lt;h1&gt;
  
  
  Hello Kotliners!
&lt;/h1&gt;

&lt;p&gt;In this article we'll see how to test Spring Boot apps using the &lt;a href="https://github.com/Kotest/Kotest" rel="noopener noreferrer"&gt;Kotest Framework&lt;/a&gt;. We'll see some examples on how we test things using JUnit, and how to easily move to Kotest and enjoy it's features.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 simple steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add Kotest's Spring Extension to your &lt;code&gt;build.gradle&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Transform your JUnit test into Kotest format (or create a new test from scratch)&lt;/li&gt;
&lt;li&gt;Add the SpringListener to your class&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Add Kotest Spring Extension
&lt;/h2&gt;

&lt;p&gt;On your &lt;code&gt;build.gradle&lt;/code&gt; file we'll add the Spring Extension dependency as a &lt;code&gt;testImplementation&lt;/code&gt;. I'm assuming you already have Kotest configured. If you don't, &lt;a href="https://github.com/Kotest/Kotest#use" rel="noopener noreferrer"&gt;take a look at the docs&lt;/a&gt; on how to do it.&lt;/p&gt;




&lt;p&gt;I like to keep the Spring Extension definition close to my Kotest definition&lt;/p&gt;

&lt;p&gt;build.gradle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    // ... Your dependencies ... 

    // Kotest
    testImplementation("io.kotest:kotest-runner-junit5:{version}")
    testImplementation("ioio.kotest.extensions:kotest-extensions-spring:{version}")

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://search.maven.org/artifact/io.kotest.extensions/kotest-extensions-spring" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fmaven-central%2Fv%2Fio.kotest.extensions%2Fkotest-extensions-spring.svg%3Flabel%3Dlatest%2520release" width="130" height="20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Transform a JUnit test to a Kotest Spec
&lt;/h2&gt;

&lt;p&gt;For this part we'll assume that we already have a component in our application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bar"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes yes, it's very simple and very dummy... But stay with me, we will go step by step!&lt;/p&gt;

&lt;p&gt;We usually write a JUnit + Spring integrated test for this, validating that this bean works correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.baeldung.com/spring-boot-testing" rel="noopener noreferrer"&gt;There&lt;/a&gt;.&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html" rel="noopener noreferrer"&gt;are&lt;/a&gt;.&lt;a href="https://spring.io/guides/gs/testing-web/" rel="noopener noreferrer"&gt;many&lt;/a&gt;.&lt;a href="https://reflectoring.io/unit-testing-spring-boot/" rel="noopener noreferrer"&gt;guides&lt;/a&gt; that show us how to do it. Let's take this basic approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringRunner&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponentTest&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;simpleComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponent&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fooShouldReturnBar&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nc"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;simpleComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Transform that test in a Kotest Spec
&lt;/h2&gt;

&lt;p&gt;There are a &lt;a href="https://github.com/Kotest/Kotest/blob/master/doc/styles.md" rel="noopener noreferrer"&gt;lot of styles&lt;/a&gt; that can be used in Kotest, let's try with &lt;code&gt;FunSpec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's convert it exactly as is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringRunner&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponentTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;simpleComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponent&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo should return Bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;simpleComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"Bar"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aaaand our test crashes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kotlin.UninitializedPropertyAccessException: lateinit property simpleComponent has not been initialized&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's ok, it's ok! We need to tell Kotest that this is a Spring Test!&lt;/p&gt;

&lt;h2&gt;
  
  
  Add the SpringListener to the class
&lt;/h2&gt;

&lt;p&gt;To fix the above error, we need to add the &lt;code&gt;SpringListener&lt;/code&gt; to our class' listeners:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponentTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TestListener&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringListener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;simpleComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;SimpleComponent&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo should return Bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;simpleComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"Bar"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we also removed the &lt;code&gt;@RunWith(SpringRunner::class)&lt;/code&gt;, as we are not running with JUnit anymore.&lt;/p&gt;

&lt;h4&gt;
  
  
  And &lt;em&gt;voilà&lt;/em&gt;, it works!
&lt;/h4&gt;

&lt;p&gt;Of course this is a very modest example. What about all the other configurations? Profiles, context configuration, TestConfiguration?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Don't worry!&lt;/em&gt; they'll work the same way as we're used to in JUnit. Annotating the constructor and such.&lt;/p&gt;

&lt;p&gt;For example, messing with profiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Components&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@ActiveProfiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test-profile"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActiveProfileSpringTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FunSpec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringListener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\${test-foo}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;testFoo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Should load active profile properties correctly"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;testFoo&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="s"&gt;"bar"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/kotest/kotest-extensions-spring/blob/master/src/test/kotlin/io/kotest/extensions/spring/ActiveProfileSpringTest.kt" rel="noopener noreferrer"&gt;test from Kotest test suite&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;And this is all we have for today! Go ahead and test your Spring Apps with Kotest! More information on this extension can be found at &lt;a href="https://kotest.io/docs/extensions/spring.html" rel="noopener noreferrer"&gt;the docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doubts? Suggestions? Leave us a comment!&lt;/p&gt;

</description>
      <category>kotest</category>
      <category>kotlin</category>
      <category>testing</category>
      <category>spring</category>
    </item>
  </channel>
</rss>
