<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" 
  xmlns:content="http://purl.org/rss/1.0/modules/content/" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" 
  xmlns:atom="http://www.w3.org/2005/Atom" 
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" 
  xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>spock on Solid Soft</title>
    <link>https://blog.solidsoft.pl/tags/spock/</link>
    <description>Recent content in spock on Solid Soft</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>©{year}, All Rights Reserved</copyright>
    <lastBuildDate>Tue, 05 Apr 2022 10:00:00 +0200</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>2</sy:updateFrequency>
    
        <atom:link href="https://blog.solidsoft.pl/tags/spock/index.xml" rel="self" type="application/rss+xml" />
    
    
    

      
      <item>
        <title>More compact parameterized tests reporting in Spock 2.1</title>
        <link>https://blog.solidsoft.pl/2022/04/05/more-compact-parameterized-tests-reporting-in-spock-2.1/</link>
        <pubDate>Tue, 05 Apr 2022 10:00:00 +0200</pubDate>
        
        <atom:modified>Tue, 05 Apr 2022 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2022/04/05/more-compact-parameterized-tests-reporting-in-spock-2.1/</guid>
        <description>Get even more compact reporting for parameterized tests with Spock 2.1.
  Historical background TL;TR. To just get a recipe, jump to the &amp;ldquo;More compact reporting&amp;rdquo; section. Parameterized tests, a place where Spock excels. A beautiful and powerful mechanism to reduce duplication across tests with a very readable table-like data representation (and powerful data providers if sophisticated custom logic is required).
When I started using Spock years ago (0.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Get even more compact reporting for parameterized tests with Spock 2.1.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2022/spock21-improved-unrolling.jpg&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;historical-background&#34;&gt;Historical background&lt;/h2&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;strong&gt;TL;TR&lt;/strong&gt;. To just get a recipe, jump to the &lt;a href=&#34;#more-compact-reporting&#34;&gt;&amp;ldquo;More compact reporting&amp;rdquo; section&lt;/a&gt;.&lt;/div&gt;

&lt;p&gt;Parameterized tests, a place where Spock excels. A beautiful and powerful mechanism to reduce duplication across tests with a very readable table-like data representation (and powerful data providers if sophisticated custom logic is required).&lt;/p&gt;
&lt;p&gt;When I started using Spock years ago (0.6?), one question perpetually dinned in somebody&amp;rsquo;s ears. Why unrolling was not enabled by default? Adding &lt;code&gt;@Unroll&lt;/code&gt; (even at the test class level) was for me redundant, error prone and&amp;hellip; just boring. Due to that, I created a small &lt;a href=&#34;https://github.com/szpak/spock-global-unroll&#34; target=&#34;_blank&#34;&gt;spock-global-unroll&lt;/a&gt;
 extension which was dead simple. It was enough to just put it on a classpath (i.e. add as a dependency in Gradle or Maven) to have all the parameterized tests automatically unrolled in the whole project. Zero configuration, it just worked. You could remove all &lt;code&gt;@Unroll&lt;/code&gt; annotation (without parameters) in your project. I really liked it and used it in every project I had my fingers in. Have you ever heard about it?&lt;/p&gt;
&lt;p&gt;It was a rhetorical question. The vast majority of you did not. Why? Because it was an extension and people start looking for extensions when something does not work. For the extensions that improve (even dramatically) some aspect of your tests you would need to hear about them before (and I am hopeless at self promotion :-/).&lt;/p&gt;
&lt;p&gt;That was a reason why I &lt;a href=&#34;https://github.com/spockframework/spock/issues/967&#34; target=&#34;_blank&#34;&gt;pushed hard&lt;/a&gt;
 to have it available and enabled by default in the core of Spock 2.0. With a comprehensive implementation by &lt;a href=&#34;https://github.com/spockframework/spock/pull/1101&#34; target=&#34;_blank&#34;&gt;Björn Kautler&lt;/a&gt;
 in landed in 2.0-M3 to stay there for good. However, preparing some time ago my presentation &lt;a href=&#34;https://2022.geecon.org/speakers/info.html?id=647&#34; target=&#34;_blank&#34;&gt;&amp;ldquo;What you can expect from Spock 2?&amp;quot;&lt;/a&gt;
, I&amp;rsquo;ve noticed that it could be improved even more.&lt;/p&gt;
&lt;h2 id=&#34;default-verbose-reporting&#34;&gt;Default (verbose) reporting&lt;/h2&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;strong&gt;Performance tip&lt;/strong&gt;. For Gradle projects, I prefer to execute unit and integration tests directly by IDEA, not by IDEA using Gradle (which - unfortunately - has been a default option since 2019 or so). First of all, it is much faster - a crucioal thing for TDD - and in the majority of cases it works perfectly fine. The examples below use that mode. You can read how to speed up your unit tests execution in my another blog post.&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s assume we have a simple parameterized test:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;UnrollSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;

    &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should calculate number of characters in given animal name&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;expect:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;animalName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedLength&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;where:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;animalName&lt;/span&gt;     &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedLength&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&amp;#34;dog&amp;#34;&lt;/span&gt;          &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&amp;#34;wolf&amp;#34;&lt;/span&gt;         &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&amp;#34;hippopotamus&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Spock 2 unrolls parameterized tests by default displaying also all the used parameters. However, the output in IDEA is hard to read:&lt;/p&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2022/spock21-long2-unroll.png&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
To see the parameters it is usually needed to scroll the result window horizontally (if luckily your fancy mouse supports that :-) ) or reduce space available for the test standard output.&lt;/p&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2022/spock21-long-unroll.png&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
The crazy idea sprang in my mind - could the (repeated) feature name be omitted in the iterations name?&lt;/p&gt;
&lt;p&gt;To remove it for a particular test it is easy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Unroll&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;animaName: #animalName, expectedLength: #expectedLength&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//inconvenient - just for one test
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should calculate number of characters in given animal name&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;However, we have been just celebrating the removal of &lt;code&gt;@Unroll&lt;/code&gt;, not to be forced to put it back everywhere&amp;hellip; Luckily, Spock has a global configuration mechanism, could not it be used?&lt;/p&gt;
&lt;p&gt;After some minutes when I was analyzing the &lt;code&gt;UnrollExtension&lt;/code&gt; code, it turned out that no. &lt;code&gt;SpockConfig.groovy&lt;/code&gt; allows to define a custom &lt;code&gt;defaultPattern&lt;/code&gt;, but there is no way to display just the parameters. It is a FOSS project, what should be done in that case? :-)&lt;/p&gt;
&lt;h2 id=&#34;more-compact-reporting&#34;&gt;More compact reporting&lt;/h2&gt;
&lt;p&gt;The idea described in the previous section resulted in the improvements in Spock 2.1. There is a new configuration parameter which needs to be placed inside the &lt;code&gt;unroll {}&lt;/code&gt; closure in the &lt;code&gt;SpockConfig.groovy&lt;/code&gt; file (located for example in &lt;code&gt;src/test/resources&lt;/code&gt; - NOT together with the test classes):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//in SpockConfig.groovy
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unroll&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;includeFeatureNameForIterations&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2022/spock21-short2-unroll.png&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
Much shorter, still meaningful output. And for all tests in the project!&lt;/p&gt;
&lt;p&gt;Note. If for some reason, you want to use it just for individual features &lt;code&gt;@Unroll(&#39;#dataVariablesWithIndex&#39;)&lt;/code&gt; can be used as well. Please refer the &lt;a href=&#34;https://spockframework.org/spock/docs/2.1/data_driven_testing.html#_configuration&#34; target=&#34;_blank&#34;&gt;official documentation&lt;/a&gt;
 for other use cases.&lt;/p&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;Keep in mind that &lt;code&gt;SpockConfig.groovy&lt;/code&gt; can &lt;a href=&#34;https://spockframework.org/spock/docs/2.1/extensions.html#spock-configuration-file&#34;&gt;be placed in various places&lt;/a&gt;, including your home directory - to more global impact.&lt;/div&gt;

&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;p&gt;Why that marvelous feature was not enabled by default in Spock 2.1? We were thinking about that, but there two arguments against:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Backward compatibility.&lt;/li&gt;
&lt;li&gt;Poor support in some reporting tools.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
The second point was more important. While the IDEA represents the test results with a very nice tree-like view, some other tools are not. The test report generated by Gradle or Maven&amp;rsquo;s Surefire displays them as a flat list, without the (parent) test name. As a result, not having the feature name in every iteration could be confusing.&lt;/p&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2022/spock21-gradle-reporting2.png&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
As a result you might want to enable that feature conditionally only if executed in IDEA, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//in SpockConfig.groovy
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;boolean&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;isExecutedFromIdea&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;java.class.path&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;contains&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;idea_rt.jar&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//any more reliable way?
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;unroll&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;includeFeatureNameForIterations&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isExecutedFromIdea&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;That check is somehow fragile (e.g. doesn&amp;rsquo;t work if IDEA executes tests not directly, but using Gradle), but I wasn&amp;rsquo;t able to find anything better. Feel free to put your proposal in the comments.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;I hope that you also found &lt;code&gt;includeFeatureNameForIterations false&lt;/code&gt; useful. Hopefully, having better support in the reporting tools there will be no obstacles to make it enabled by default in Spock 3.0.&lt;/p&gt;
&lt;p&gt;Btw, in the middle of May, I will be talking about that and other new and noteworthy in Spock 2 at the &lt;a href=&#34;https://2022.geecon.org/speakers/info.html?id=647&#34; target=&#34;_blank&#34;&gt;GeeCON conference&lt;/a&gt;
. This time, finally, on-site, in Kraków, Poland (but the whole conference is in English).&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://2022.geecon.org/&#34; target=&#34;_blank&#34;&gt;

&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2022/spock21-geecon2022-big.png&#34; alt=&#34;GeeCON 2022 banner&#34; style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/paulina101-506132/&#34;&gt;Paulina101&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/photos/cd-cd-rom-spindle-reflection-517697/&#34;&gt;Pixabay&lt;/a&gt;, Pixabay License.&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2022/spock21-improved-unrolling-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2022/spock21-improved-unrolling-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>spock</category>
            
          
            
              <category>spock2</category>
            
          
            
              <category>spock-2.1</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>groovy</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>Running Spock with unsupported Groovy version (Gradle &#43; Maven)</title>
        <link>https://blog.solidsoft.pl/2021/11/19/running-spock-with-unsupported-groovy-version-gradle-maven/</link>
        <pubDate>Fri, 19 Nov 2021 00:10:00 +0200</pubDate>
        
        <atom:modified>Wed, 02 Feb 2022 23:50:00 +0100</atom:modified>
        <guid>https://blog.solidsoft.pl/2021/11/19/running-spock-with-unsupported-groovy-version-gradle-maven/</guid>
        <description>Stuck with the &amp;lsquo;The Spock compiler plugin cannot execute because Spock 1.3-groovy-2.5 (3.0) is not compatible with Groovy 3.0 (4.0)&amp;rsquo; error message? Find out what can be done about that (using Gradle and Maven).
  Historical background In the dim and distance past, when Groovy 1.x occasionally had some unpleasant (also runtime) backward compatibility issues, Spock had started to be built for the particular Groovy version individually. There were spock-0.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Stuck with the &amp;lsquo;The Spock compiler plugin cannot execute because Spock 1.3-groovy-2.5 (3.0) is not compatible with Groovy 3.0 (4.0)&amp;rsquo; error message? Find out what can be done about that (using Gradle and Maven).&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2021/spock2-groovy4.jpg&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;historical-background&#34;&gt;Historical background&lt;/h2&gt;
&lt;p&gt;In the dim and distance past, when Groovy 1.x occasionally had some unpleasant (also runtime) backward compatibility issues, Spock had started to be built for the particular Groovy version individually. There were &lt;code&gt;spock-0.5-groovy-1.6&lt;/code&gt;, &lt;code&gt;spock-0.5-groovy-1.7&lt;/code&gt; and &lt;code&gt;spock-0.5-groovy-1.8&lt;/code&gt; for instance. To help people choose the right Spock and the Groovy versions, the runtime check was added to fail the compilation (at the AST transformation level) with the meaningful error message, in the situation Spock was compiled with the different Groovy version that is available at runtime, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The Spock compiler plugin refused to run because Spock 1.3-groovy-2.5 is not compatible with Groovy 3.0.4. For more information,
see http://versioncheck.spockframework.org Spock location: .../spock-1.3-groovy-2.5.jar, Groovy location: .../groovy-3.0.4.jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The error message is very clear. The reasoning behind this decision is good, and definitely it can help developers to detect problems with the dependencies. However, it can also greatly complicate development, especially taking into account rather rarely released new Spock versions.&lt;/p&gt;
&lt;p&gt;If you are here, because of that error visible in your build, jump to the proper section to see what can be done about the problem.&lt;/p&gt;
&lt;h2 id=&#34;possible-options&#34;&gt;Possible options&lt;/h2&gt;
&lt;h3 id=&#34;spock-13-and-groovy-30&#34;&gt;Spock 1.3 and Groovy 3.0&lt;/h3&gt;
&lt;p&gt;Unfortunately, you are out of luck. If you stuck with Spock 1.3 (e.g. migration to Spock 2.0 is blocked for some reasons) there are two (mediocre) options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Switch to &lt;code&gt;Spock 1.3-SNAPSHOT&lt;/code&gt;. The version compatibility check is relaxed in the SNAPSHOT builds of Spock 1.3. What&amp;rsquo;s more, there were multiple reports that (in the majority of cases - some corner cases remains) Spock &lt;code&gt;1.3-groovy-2.5-SNAPSHOT&lt;/code&gt; works fine with Groovy &lt;code&gt;3.0.x&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are no plans to release any new maintenance release of Spock 1.x. However, you can still &lt;a href=&#34;https://github.com/spockframework/spock/issues&#34; target=&#34;_blank&#34;&gt;create a new issue on GitHub&lt;/a&gt;
 and try to convince The Spock Developers to make 1.3.1 with that change :-).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;spock-20-and-groovy-30&#34;&gt;Spock 2.0+ and Groovy 3.0&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;The Spock compiler plugin refused to run because Spock 2.0-groovy-2.5 is not compatible with Groovy 3.0.9.
For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;). 
Spock location: .../spock-2.0-groovy-2.5.jar
Groovy location: .../groovy-3.0.9.jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That a trivial case. Just change Spock version from 2.0-groovy-2.5 to 2.0-groovy-3.0, and you are set.&lt;/p&gt;
&lt;h3 id=&#34;spock-2021-and-groovy-40&#34;&gt;Spock 2.0/2.1 and Groovy 4.0&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;The Spock compiler plugin refused to run because Spock 2.0-groovy-3.0 is not compatible with Groovy 4.0.0-beta-2.
For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;). 
Spock location: .../spock-2.0-groovy-3.0.jar
Groovy location: .../groovy-4.0.0-beta-2.jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This variant assumes that you use Groovy 4 (SNAPSHOT, beta or a regular version) and Spock 2.0-groovy-3.0 (or 2.1). The error message is even more precise than in Spock 1.3, suggesting the &lt;a href=&#34;http://spockframework.org/spock/docs/2.0-M3/known_issues.html#_groovy_version_compatibility&#34; target=&#34;_blank&#34;&gt;&amp;lsquo;Known Issues&amp;rsquo;&lt;/a&gt;
 section in the Spock documentation. We can leverage a brand-new system property &lt;code&gt;spock.iKnowWhatImDoing.disableGroovyVersionCheck&lt;/code&gt;, introduced right in Spock 2.0-M3, which allows to disable the version check - of course, at your own risk :-).&lt;/p&gt;
&lt;p&gt;Btw, if you in a hurry (e.g. just to test something), it is also possible just to switch Spock to SNAPSHOT version which accepts (almost) any Groovy version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Btw2, if you prefer to just jump into code, there is a &lt;a href=&#34;https://github.com/szpak/code-examples-and-poc/tree/master/spock2-groovy4-gradle-maven&#34; target=&#34;_blank&#34;&gt;code repository&lt;/a&gt;
 with working examples for Gradle and Maven.&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;gradle&#34;&gt;Gradle&lt;/h4&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;As Groovy 4 changed its &lt;code&gt;groupId&lt;/code&gt; from &lt;code&gt;org.codehaus.groovy&lt;/code&gt; to &lt;code&gt;org.apache.groovy&lt;/code&gt; it is required to &lt;strong&gt;add implicit exclusion for spock-2.0-groovy-3.0 transitive dependencies&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;testImplementation(&amp;quot;org.spockframework:spock-core:2.0-groovy-3.0&amp;quot;) {
    exclude group: &#39;org.codehaus.groovy&#39;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to avoid conflicting Groovy versions on a classpath (it&amp;rsquo;s nice that Gradle is able to detect that!):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task &#39;:compileTestGroovy&#39;.
&amp;gt; Could not resolve all files for configuration &#39;:testCompileClasspath&#39;.
   &amp;gt; Could not resolve org.apache.groovy:groovy:4.0.0-beta-2.
     Required by:
         project :
         project : &amp;gt; org.apache.groovy:groovy:4.0.0-beta-2 &amp;gt; org.apache.groovy:groovy-bom:4.0.0-beta-2
      &amp;gt; Module &#39;org.apache.groovy:groovy&#39; has been rejected:
           Cannot select module with conflict on capability &#39;org.codehaus.groovy:groovy:4.0.0-beta-2&#39; also provided by [org.codehaus.groovy:groovy:3.0.8(compile)]
   &amp;gt; Could not resolve org.codehaus.groovy:groovy:3.0.8.
     Required by:
         project : &amp;gt; org.spockframework:spock-core:2.0-groovy-3.0
      &amp;gt; Module &#39;org.codehaus.groovy:groovy&#39; has been rejected:
           Cannot select module with conflict on capability &#39;org.codehaus.groovy:groovy:3.0.8&#39; also provided by [org.apache.groovy:groovy:4.0.0-beta-2(groovyApiElements)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It won&amp;rsquo;t be required for Spock 2.0-groovy-4.0, once available.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;strong&gt;To be able use Groovy 4, Gradle 6.7+ is &lt;a href=&#34;https://github.com/gradle/gradle/issues/13657&#34;&gt;required&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With earlier Gradle version you might got some misleading errors about not resolvable dependency to &lt;code&gt;org.codehaus.groovy:groovy:4.0.0-beta-2&lt;/code&gt;, even though you configured &lt;code&gt;org.apache.groovy:groovy:4.0.0-beta-2&lt;/code&gt; with the correct, changed group id.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Execution failed for task &#39;:compileTestGroovy&#39;.
&amp;gt; Could not resolve all files for configuration &#39;:detachedConfiguration1&#39;.
   &amp;gt; Could not find org.codehaus.groovy:groovy:4.0.0-beta-2.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The obvious way to add system properties to the Gradle execution itself is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./gradlew check -Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true     //wrong way
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately it doesn&amp;rsquo;t work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED
startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/spock-core-2.0-groovy-3.0.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 2.0-groovy-3.0 is not compatible with Groovy 4.0.0-beta-2. For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;).
Spock artifact: file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/.../spock-core-2.0-groovy-3.0.jar
Groovy artifact: file:/home/foobar/.gradle/caches/modules-2/files-2.1/org.apache.groovy/groovy/4.0.0-beta-2/.../groovy-4.0.0-beta-2.jar

1 error


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task &#39;:compileTestGroovy&#39;.
&amp;gt; Compilation failed; see the compiler error output for details.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After some searching on the Internet, we can find out that tests in Gradle are (by default) executed in a separate JVM, to it is required to pass the aforementioned system property to the &lt;code&gt;test&lt;/code&gt; task:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;systemProperty&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//doesn&amp;#39;t work
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;However, it still fails:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED
startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hmm, maybe it would be better to refer the Gradle test task by type?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Test&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configureEach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;systemProperty&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//doesn&amp;#39;t work either
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It fails with the same error message :-/. What is wrong?&lt;/p&gt;
&lt;p&gt;The key difference - quite easy to miss - is the fact the exception is thrown not during the test execution, but during the compilation phrase. Then, the main Spock AST transformation checks if it could be applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED   &amp;lt;--------- :compileTestGroovy not :test !
startup failed:
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is definitely less popular case, and I had a problem to find any sensible source of wisdom proposing a complete solution. One of the possible option (which I talk about deeper in the article about &lt;a href=&#34;https://blog.solidsoft.pl/2020/03/02/enable-java-14-preview-features-in-gradle-maven-and-idea/&#34;&gt;enabling preview features&lt;/a&gt;
 of the new Java versions) is &lt;code&gt;CompileOptions&lt;/code&gt; (e.g. &lt;code&gt;options.compilerArgs.add(&#39;--enable-preview&#39;)&lt;/code&gt; in the &lt;a href=&#34;https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/compile/GroovyCompile.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;GroovyCompile&lt;/code&gt;&lt;/a&gt;
 task. The second might be &lt;code&gt;GroovyCompileOptions&lt;/code&gt; also in &lt;code&gt;GroovyCompile&lt;/code&gt;. However, it does not bring expected result. After some digging, I was able to find out, that as the Groovy compilation is performed in the forked JVM and the right way to achieve the goal is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GroovyCompile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configureEach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;forkOptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;jvmArgs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;-Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true&amp;#39;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//it works! But be aware that &amp;#34;options&amp;#34; not &amp;#34;groovyOptions&amp;#34;!
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;And it works as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy
Executing Spock 2.0-groovy-3.0 with NOT compatible Groovy version 4.0.0-beta-2 due to set spock.iKnowWhatImDoing.disableGroovyVersionCheck system property set. This is unsupported and may result in weird runtime errors!

&amp;gt; Task :test
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;displaying a nice disclaimer :). Spock 2.0-groovy-3.0 is used together with Groovy 4.&lt;/p&gt;
&lt;p&gt;Btw, if you see just not very helpful error message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at
jar:file:/.../spock-core-.../org.codehaus.groovy.transform.ASTTransformation
because of exception java.lang.reflect.InvocationTargetException
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;it is caused by &lt;a href=&#34;https://issues.apache.org/jira/browse/GROOVY-9469&#34; target=&#34;_blank&#34;&gt;GROOVY-9469&lt;/a&gt;
 which affects Groovy 3 and was fixed in 3.0.3. Upgrade Groovy to see more verbose error message.&lt;/p&gt;
&lt;h4 id=&#34;maven&#34;&gt;Maven&lt;/h4&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;As Groovy 4 changed its &lt;code&gt;groupId&lt;/code&gt; from &lt;code&gt;org.codehaus.groovy&lt;/code&gt; to &lt;code&gt;org.apache.groovy&lt;/code&gt; it is required to &lt;strong&gt;add implicit exclusion for spock-2.0-groovy-3.0 transitive dependencies&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.spockframework&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spock-core&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;${spock.version}&amp;lt;/version&amp;gt;
        &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;exclusions&amp;gt;
            &amp;lt;!-- to do not have conflicting Groovy versions - Groovy 4 changed groupId from &amp;quot;org.codehaus.groovy&amp;quot; to &amp;quot;org.apache.groovy&amp;quot; --&amp;gt;
            &amp;lt;exclusion&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.groovy&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;*&amp;lt;/artifactId&amp;gt;
            &amp;lt;/exclusion&amp;gt;
        &amp;lt;/exclusions&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.apache.groovy&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;groovy&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;4.0.0-beta-2&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to have your tests executed with Groovy 4 instead of (silently) with Groovy 3, taken from a transitive dependency of Spock 2.0-groovy-3.0!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[INFO] --- gmavenplus-plugin:1.13.0:compileTests (default) @ spock2-groovy4-maven ---
[INFO] Using isolated classloader, without GMavenPlus classpath.
[INFO] Using Groovy 3.0.8 to perform compileTests.     &amp;lt;---- Without exclusion, it is executed &amp;quot;silently&amp;quot; with old Groovy! 
[INFO] Parallel parsing disabled.
[INFO] Compiled 1 file.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It won&amp;rsquo;t be required for Spock 2.0-groovy-4.0, once available.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Writing my Spock, Groovy and modern Java related tutorials, I try to cover also the Maven users, which still is quite popular build tool :-). Usually, it takes much more (XML) lines to achieve the same in Maven in comparison to Gradle, however, sometimes it just works flawlessly without any additional effort. Unfortunately, it was not the case this time.&lt;/p&gt;
&lt;p&gt;The build with Spock-2.0-groovy-3.0 and Groovy 4.0.0 by default fails with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ERROR] Failed to execute goal org.codehaus.gmavenplus:gmavenplus-plugin:1.8.1:compileTests (default) on project spock2-migration-maven: Error occurred while calling a method on a Groovy class from classpath. InvocationTargetException: startup failed:
[ERROR] Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/spock-core-2.0-groovy-3.0.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 2.0-groovy-3.0 is not compatible with Groovy 4.0.0-beta-2. For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;).
[ERROR] Spock artifact: file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/spock-core-2.0-groovy-3.0.jar
[ERROR] Groovy artifact: file:/home/foobar/.m2/repository/org/apache/groovy/groovy/4.0.0-beta-2/groovy-4.0.0-beta-2.jar
[ERROR] 
[ERROR] 1 error
[ERROR] -&amp;gt; [Help 1]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To make the long story short, I started with the plain Maven properties:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;project&amp;gt;&lt;/span&gt;
...
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
     &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- doesn&amp;#39;t work --&amp;gt;&lt;/span&gt;
     &lt;span class=&#34;nt&#34;&gt;&amp;lt;spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
...
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It fails. Next, I added the following to the compiler parameters:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.8.1&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- doesn&amp;#39;t work --&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;compilerArgs&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;-v&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;-Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/compilerArgs&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;however, it doesn&amp;rsquo;t affect Groovy compilation itself. I even took a look at the &lt;code&gt;gmavenplus&lt;/code&gt; plugin parameters and Groovy&amp;rsquo;s &lt;a href=&#34;https://docs.groovy-lang.org/latest/html/api/org/codehaus/groovy/control/CompilerConfiguration.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;CompilerConfiguration&lt;/code&gt;&lt;/a&gt;
, but without any effect. In the end, I was able to achieve that with another plugin &lt;code&gt;properties-maven&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.mojo&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;properties-maven-plugin&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;set-system-properties&lt;span class=&#34;nt&#34;&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- works fine --&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
                            &lt;span class=&#34;nt&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;spock.iKnowWhatImDoing.disableGroovyVersionCheck&lt;span class=&#34;nt&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
                            &lt;span class=&#34;nt&#34;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;resulting in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[INFO] --- gmavenplus-plugin:1.8.1:compileTests (default) @ spock2-migration-maven ---
[INFO] Using isolated classloader, without GMavenPlus classpath.
[INFO] Using Groovy 4.0.0-beta-2 to perform compileTests.
Executing Spock 2.0-groovy-3.0 with NOT compatible Groovy version 4.0.0-beta-2 due to set spock.iKnowWhatImDoing.disableGroovyVersionCheck system property set. This is unsupported and may result in weird runtime errors!
[INFO] Compiled 10 files.
[INFO] 
[INFO] --- maven-surefire-plugin:3.0.0-M4:test (default-test) @ spock2-migration-maven ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It turned out to be quite easy (if you know what to use :-) ), but - unless I missed something - it is somehow not much covered in the existing tutorials or documentation.&lt;/p&gt;
&lt;h3 id=&#34;potential-issue-in-intellij-idea&#34;&gt;Potential issue in IntelliJ IDEA&lt;/h3&gt;
&lt;p&gt;Even though, having your up-and-running Maven project configured as above, you might still encounter the incompatibility error after importing it in Idea:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Groovyc: While compiling [tests of spock2-groovy4-gradle.test]: Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/home/&amp;hellip;/spock-core-2.0-groovy-3.0.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception java.lang.NullPointerException: Cannot invoke &amp;ldquo;java.net.URL.toString()&amp;rdquo; because the return value of &amp;ldquo;java.security.CodeSource.getLocation()&amp;rdquo; is null&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;del&gt;The problem is caused by a limitation of Idea (&lt;a href=&#34;https://youtrack.jetbrains.com/issue/IDEA-287642&#34; target=&#34;_blank&#34;&gt;IDEA-287642&lt;/a&gt;
), which does not allow providing custom system properties for groovyc compilation (just for javac). You might want to vote for that issue.&lt;/del&gt; In fact, as &lt;a href=&#34;https://youtrack.jetbrains.com/issue/IDEA-287642#focus=Comments-27-5733123.0-0&#34; target=&#34;_blank&#34;&gt;Paul King&lt;/a&gt;
 pointed out, there is a way to set that property for all the compilers used in the project with &lt;code&gt;Settings → Compiler → Shared build process VM options&lt;/code&gt;. In the context of Spock, it should be enough.&lt;/p&gt;
&lt;p&gt;The error itself is not very meaningful (&lt;code&gt;NullPointerException&lt;/code&gt;) which in turn is caused by an unexpected behavior of Idea, reported as &lt;a href=&#34;https://youtrack.jetbrains.com/issue/IDEA-287643&#34; target=&#34;_blank&#34;&gt;IDEA-287643&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;It is worth to mention, the same problem might occur also with Gradle, once &amp;ldquo;Build and run&amp;rdquo; is manually set to &amp;ldquo;Idea&amp;rdquo; (instead of &amp;ldquo;Gradle&amp;rdquo; - default behavior, but not the fastest one).&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The main reason, I implemented that feature in Spock was development of Groovy 4. I didn&amp;rsquo;t feel comfortable seeing The Groovy Team to be forced to use the Spock snapshot version in the master (Groovy 4.x) builds. With Spock-2.0-M3 it was &lt;a href=&#34;https://github.com/apache/groovy/pull/1281&#34; target=&#34;_blank&#34;&gt;simplified&lt;/a&gt;
. The same construction can be used in your project while playing with Groovy 4 (in beta as of XI 2021), in the way I precised for Gradle and Maven (which in turn can be really confusing on their own way which motivated me to write this short post :-) ). There is &lt;a href=&#34;https://github.com/spockframework/spock/issues/1374#issuecomment-932374972&#34; target=&#34;_blank&#34;&gt;a plan&lt;/a&gt;
 to add the official support for Groovy 4 in Spock, once it is closer to Groovy 4.0.0-final.&lt;/p&gt;
&lt;p&gt;Btw, there is a &lt;a href=&#34;https://github.com/szpak/code-examples-and-poc/tree/master/spock2-groovy4-gradle-maven&#34; target=&#34;_blank&#34;&gt;code repository&lt;/a&gt;
 with working examples for Gradle and Maven.&lt;/p&gt;
&lt;p&gt;P.S. If you bumped into that topic during Spock 1.3 -&amp;gt; 2.0 migration, there is a dedicated &lt;a href=&#34;https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/&#34;&gt;migration guide article&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated 2021-01-31&lt;/strong&gt;. Added section about potential issue with IntelliJ IDEA.&lt;br /&gt;
&lt;strong&gt;Updated 2021-02-02&lt;/strong&gt;. Add workaround suggested by &lt;a href=&#34;https://twitter.com/paulk_asert&#34; target=&#34;_blank&#34;&gt;Paul King&lt;/a&gt;
 about the potential issue with IntelliJ IDEA.&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/geralt-9301/&#34;&gt;geralt&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/illustrations/place-name-sign-plan-success-749613/&#34;&gt;Pixabay&lt;/a&gt;, Pixabay License.&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2021/spock2-groovy4-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2021/spock2-groovy4-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>spock</category>
            
          
            
              <category>spock2</category>
            
          
            
              <category>spock-2.0</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>groovy</category>
            
          
            
              <category>groovy4</category>
            
          
            
              <category>gradle</category>
            
          
            
              <category>maven</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>What happened to Groovy dependencies in Spock 2.0?</title>
        <link>https://blog.solidsoft.pl/2020/06/16/what-happened-to-groovy-dependencies-in-spock-2.0/</link>
        <pubDate>Tue, 16 Jun 2020 10:00:00 +0200</pubDate>
        
        <atom:modified>Tue, 16 Jun 2020 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/06/16/what-happened-to-groovy-dependencies-in-spock-2.0/</guid>
        <description>Spock 2.0(-M3) reduced number of provided Groovy dependencies. If you started to get various Groovy-related ClassNotFoundExceptions after migration and wonder why and what to do, read on.
  Historical background Originally Groovy was just one jar to rule them all. However, in process of time, that jar became bigger and bigger. Groovy 2 was the first version promoting the usage of (several at that time) Groovy modules, as a supplemental to groovy.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Spock 2.0(-M3) reduced number of provided Groovy dependencies. If you started to get various Groovy-related &lt;code&gt;ClassNotFoundException&lt;/code&gt;s after migration and wonder why and what to do, read on.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/spock-groovy-dependencies.jpg&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;historical-background&#34;&gt;Historical background&lt;/h2&gt;
&lt;p&gt;Originally Groovy was just one &lt;code&gt;jar&lt;/code&gt; to rule them all. However, in process of time, that jar became bigger and bigger. Groovy 2 was the first version promoting the usage of (several at that time) Groovy modules, as a supplemental to &lt;code&gt;groovy.jar&lt;/code&gt;. However the adoption of that approach was slowly and &lt;code&gt;groovy-all&lt;/code&gt; remained prevalent in &lt;code&gt;pom.xml&lt;/code&gt; and &lt;code&gt;build.gradle&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;What even worse, having some projects use &lt;code&gt;groovy.jar&lt;/code&gt; plus some modules (e.g. &lt;code&gt;groovy-json.jar&lt;/code&gt; or &lt;code&gt;groovy-xml.jar&lt;/code&gt;) while some other preferring good old &lt;code&gt;groovy-all.jar&lt;/code&gt; could lead to version clashes as for Maven or Gradle those were independent packages. To avoid that it was quite common to see the defensive Groovy exclusions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.gmaven.runtime&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;YYY&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.2&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.groovy&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;*&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.groovy&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;groovy-all&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${groovy.version}&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;and declare all required Groovy dependencies on their own.&lt;/p&gt;
&lt;p&gt;Groovy 2.5 switched to the model of Maven&amp;rsquo;s BOM (Bill Of Materials) where &lt;code&gt;groovy-all&lt;/code&gt; isn&amp;rsquo;t a binary jar itself, but rather has the official Groovy modules as dependencies. Thanks to that, Maven and Gradle have easier to keep the versioning of the particular modules consistent. This holds for Groovy 3 which still provides the &lt;code&gt;groovy-all&lt;/code&gt; BOM.&lt;/p&gt;
&lt;h2 id=&#34;groovy-dependencies-in-spock-13&#34;&gt;Groovy dependencies in Spock 1.3&lt;/h2&gt;
&lt;p&gt;Spock 1.2 switched from &lt;code&gt;groovy-all.jar&lt;/code&gt; to &lt;code&gt;groovy.jar&lt;/code&gt; + modules. Unfortunately due to historical reasons it was a lot of modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;testRuntimeClasspath - Runtime classpath of source set &#39;test&#39;.
+--- org.spockframework:spock-core:2.0-M2-groovy-3.0
|    +--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-json:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-nio:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-macro:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-templates:3.0.0
|    |    +--- org.codehaus.groovy:groovy-xml:3.0.0
|    |    |    \--- org.codehaus.groovy:groovy:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-test:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-sql:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-xml:3.0.0 (*)
|    \--- org.junit.platform:junit-platform-engine:1.5.2
|         ...
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As a result the following was quite common:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:1.3-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;exclude&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;group:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.codehaus.groovy&amp;#39;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//get rid of all dependant groovy modules
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.codehaus.groovy:groovy:2.5.11&amp;#39;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//apply only those needed
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.codehaus.groovy:groovy-json:2.5.11&amp;#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.codehaus.groovy:groovy-templates:2.5.11&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;However, it turned out that in fact all those extra modules are not needed internally for &lt;code&gt;spock-core&lt;/code&gt; and they were rather provided as a convenience for end users.&lt;/p&gt;
&lt;h2 id=&#34;groovy-dependencies-in-spock-20&#34;&gt;Groovy dependencies in Spock 2.0+&lt;/h2&gt;
&lt;p&gt;Starting with Spock 2.0-M3 the Groovy dependencies were &lt;a href=&#34;https://github.com/spockframework/spock/pull/1109&#34; target=&#34;_blank&#34;&gt;simplified&lt;/a&gt;
 to just &lt;code&gt;groovy.jar&lt;/code&gt;. Thanks to that you safe some bandwidth on the initial build (what is well-timed ;-) ) and the CI builds without proper caching take slightly shorter.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;testCompileClasspath - Compile classpath for source set &#39;test&#39;.
+--- org.spockframework:spock-core:2.0-M3-groovy-3.0
|    +--- org.codehaus.groovy:groovy:3.0.4
|    +--- org.junit.platform:junit-platform-engine:1.7.1-M1
|         ...
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As a downside, after the migration to Spock-2.0-M3+, in rare cases you might get &lt;code&gt;ClassNotFoundException: groovy.sql.Sql&lt;/code&gt;, &lt;code&gt;ClassNotFoundException: groovy.json.JsonSlurper&lt;/code&gt; or &lt;code&gt;ClassNotFoundException: groovy.util.XmlParser&lt;/code&gt;. That error suggest that you use those classes somewhere in your tests, but the corresponding dependency is not declared implicitly in your build configuration (and it&amp;rsquo;s not accidentally provided by &lt;code&gt;spock-core&lt;/code&gt; any longer). The quick fix is to add &lt;code&gt;org.codehaus.groovy:groovy-sql:3.0.X&lt;/code&gt;, &lt;code&gt;org.codehaus.groovy:groovy-json:3.0.X&lt;/code&gt; or similar explicitly.&lt;/p&gt;
&lt;p&gt;P.S. If you bumped into that topic during Spock 1.3 -&amp;gt; 2.0 migration, there is a dedicated &lt;a href=&#34;https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/&#34;&gt;migration guide article&lt;/a&gt;
.&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/tumisu-148124/&#34;&gt;Tumisu&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/photos/magnifying-glass-detective-looking-4340698/&#34;&gt;Pixabay&lt;/a&gt;, Pixabay License.&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock-groovy-dependencies-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock-groovy-dependencies-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>spock</category>
            
          
            
              <category>spock2</category>
            
          
            
              <category>spock-2.0</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>groovy</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>Spock vs JUnit 5 - the ultimate feature comparison</title>
        <link>https://blog.solidsoft.pl/2020/04/15/spock-vs-junit-5-the-ultimate-feature-comparison/</link>
        <pubDate>Wed, 15 Apr 2020 10:00:00 +0200</pubDate>
        
        <atom:modified>Wed, 15 Apr 2020 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/04/15/spock-vs-junit-5-the-ultimate-feature-comparison/</guid>
        <description>What is the best testing framework for Java code nowadays? Spock or JUnit 5? Check it out in this ultimate feature comparison.
  Spock was a game changer for all the people struggling with unit testing in JUnit 4. Compact syntax, parameterized tests or flexibility to mention just a few advantages. Over 10 years after JUnit 4.0, the brand new, written from scratch, Java 8 optimized Junit 5 has been released.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;What is the best testing framework for Java code nowadays? Spock or JUnit 5? Check it out in this ultimate feature comparison.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/spock-vs-junit5.png&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;p&gt;Spock was a game changer for all the people struggling with unit testing in JUnit 4. Compact syntax, parameterized tests or flexibility to mention just a few advantages. Over 10 years after JUnit 4.0, the brand new, written from scratch, Java 8 optimized Junit 5 has been released. And time has not stopped then.&lt;/p&gt;
&lt;p&gt;In this blog post, I will compare selected areas of Spock and JUnit 5 to give you an overview how the situation looks like nowadays. I will try to answer the question if its time for Spock to fade into oblivion or maybe quite the opposite it is still light years ahead of JUnit 5.&lt;/p&gt;
&lt;div class=&#34;notices info&#34; &gt;
  This blog post is a written version of my presentation titled &amp;ldquo;Spock vs JUnit 5 - Clash of the Titans&amp;rdquo;. If you prefer, feel free to &lt;a href=&#34;https://speakerdeck.com/szpak/spock-vs-junit-5-clash-of-the-titans&#34;&gt;see the slides&lt;/a&gt; or &lt;a href=&#34;https://www.youtube.com/watch?v=aavtOBuzVcc&#34;&gt;watch the video&lt;/a&gt; instead.
&lt;/div&gt;
&lt;h2 id=&#34;historical-background&#34;&gt;Historical background&lt;/h2&gt;
&lt;p&gt;As a warm-up, let&amp;rsquo;s take a look at the important dates in the automatic code testing in Java.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2000 - JUnit - first xUnit for Java&lt;/li&gt;
&lt;li&gt;2004 - TestNG - Java 5 (annotations) leveraged in tests
&lt;ul&gt;
&lt;li&gt;with some unique (at the time) features (such as parameterized tests, test repetition or test dependency)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2006 - JUnit 4 - Java 5 support
&lt;ul&gt;
&lt;li&gt;catching up TestNG features over the next few years&lt;/li&gt;
&lt;li&gt;de facto standard (the world chose :-/ ), steady evolution rather than revolution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2009 - Spock - revamped test creation
&lt;ul&gt;
&lt;li&gt;fresh ideas and power of Groovy under the hood&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2017 - JUnit 5 - redesigned and rewritten from scratch
&lt;ul&gt;
&lt;li&gt;new king of the hill? - let&amp;rsquo;s check it out!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;notices warning&#34; &gt;
  This comparison covers the latest released stable versions (as of April 2020) of JUnit (5.6) and Spock (1.3). I am fully aware of in-development &lt;a href=&#34;https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/&#34;&gt;Spock 2.0&lt;/a&gt; and I plan to update this comparison (or write a supplement post) once 2.0-final is available.
&lt;/div&gt;
&lt;h2 id=&#34;development-comparison&#34;&gt;Development comparison&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start with a comparison of some biased aspects of development of JUnit 5 and Spock.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;JUnit 5 &lt;span class=&#34;table-smaller&#34;&gt;(as of 5.6)&lt;/span&gt;&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;Spock &lt;span class=&#34;table-smaller&#34;&gt;(as of 1.3)&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;inception year&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;2015&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;2009&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;number of GitHub stars&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;3,7K&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;~2,6K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;number of commits&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;~6K&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;~2,5K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;development activity&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;high &lt;span class=&#34;table-smaller&#34;&gt;(young project)&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;medium &lt;span class=&#34;table-smaller&#34;&gt;(mature project)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;number of &lt;strong&gt;active&lt;/strong&gt; committers&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;3&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;1 + 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;number of contributors (ever)&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;~130&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;~80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The first thing to notice is the fact that JUnit 5 is much younger project with very high development activity. There are 3 active committers with a bunch of external contributors.&lt;/p&gt;
&lt;p&gt;One the other hand, Spock is much more mature with lower development activity. However, many of the features developed in JUnit 5 recently were already available in Spock. Therefor, the need for lots of commit in Spock is lower. Spock has currently one main maintainer and 2-3 people regularly contributing to the project (of course also with a pack of external contributors).&lt;/p&gt;
&lt;h3 id=&#34;partial-verdict&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-success&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Development: &lt;strong&gt;JUnit 5 wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;Mainly thanks to more active development activity in recent years.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;tool-support&#34;&gt;Tool support&lt;/h2&gt;
&lt;p&gt;The next thing to cover is Java 11 compatibility and support in tools.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;JUnit 5&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;Spock&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Java 11+&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;very good&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;good &lt;span class=&#34;table-smaller&#34;&gt;(with modern Groovy 2.5.x)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IntelliJ IDEA&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;built-in&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;built-in &lt;span class=&#34;table-smaller&#34;&gt;(some Groovy limitations)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eclipse&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;build-in&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;built-in &lt;span class=&#34;table-smaller&#34;&gt;(some Groovy limitations)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netbeans&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;&lt;span style=&#34;color: orange&#34;&gt;10.0+ &lt;span class=&#34;table-smaller&#34;&gt;(Maven only)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;&lt;span style=&#34;color: orange&#34;&gt;unknown&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maven&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;plugin &lt;span class=&#34;table-smaller&#34;&gt;(official, Surefire)&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;plugin &lt;span class=&#34;table-smaller&#34;&gt;(GMavenPlus for Groovy)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gradle&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;built-in&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SonarQube&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;built-in&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;plugin &lt;span class=&#34;table-smaller&#34;&gt;(official for Groovy)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PIT - mutation testing&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;plugin &lt;span class=&#34;table-smaller&#34;&gt;(official)&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;build-in&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both of the frameworks are currently very well supported in the Java ecosystem. However, it is worth to mention that tests (specifications) in Spock are written in Groovy (which notabene is the main power of Spock). As a downside, due to much more dynamic nature of Groovy as a language, IDEs have much harder time to provide as good support for it as for Java (e.g. refactoring or compile time error reporting).&lt;/p&gt;
&lt;p&gt;Regarding Java 11 and Spock, with modern Groovy 2.5.x it should work flawlessly. In general, most of the things should work fine also with Java 12, 13 and (with Groovy 2.5.10+) also 14. The official Java 14+ support should be available in Spock 2.0 (still in development) with Groovy 3.0.&lt;/p&gt;
&lt;p&gt;On the other hand, JUnit 5 is a role model on that field. It is continuously tested on a CI server with the recent Java versions (including the early access builds, such as OpenJDK 15 EA).&lt;/p&gt;
&lt;h3 id=&#34;partial-verdict-1&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-success&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Tool support: &lt;strong&gt;JUnit 5 wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;Great IDE support for Java code and continuous testing with the bleeding edge versions of Java.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;test-structure&#34;&gt;Test structure&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s move on to less technical aspects of test development - test structure.&lt;/p&gt;
&lt;p&gt;As die-hard followers of my blog may know, I am a big propagator of well structured automatic tests with the BDD-originated given-when-then concept. In short, it unifies test creation, improves their readability and makes it easier to write, especially for less experienced people. To learn more, please take a loot at a &lt;a href=&#34;https://solidsoft.wordpress.com/2017/05/16/importance-of-given-when-then-in-unit-tests-and-tdd/&#34; target=&#34;_blank&#34;&gt;separate blog post&lt;/a&gt;
 that I wrote some time ago.&lt;/p&gt;
&lt;h3 id=&#34;junit-5&#34;&gt;JUnit 5&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SimpleCalculatorTest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
    &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldAddTwoNumbers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;//given
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;Calculator&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calculator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Calculator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;//when
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calculator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;//then
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;assertEquals&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The given-when-then sections are marked just by plain comments in code. It is not perfect. They might be forgotten and are easy to lost/misplace during refactoring. Could it be done better?&lt;/p&gt;
&lt;h3 id=&#34;spock&#34;&gt;Spock&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SimpleCalculatorSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should add two numbers&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;given:&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;Calculator&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calculator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Calculator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calculator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Well, in Spock the (almost not used in Java) &lt;code&gt;label&lt;/code&gt; construction is leveraged. It is crucial to highlight that they are not just comments in code - they are a part of the specification. For example, having &lt;code&gt;when:&lt;/code&gt; removed in the example above, generates real compilation errors. Nice.&lt;/p&gt;
&lt;p&gt;Btw, of course, in Spock it is possible to write just one-liners, if feasible. However, developers have to do it intently.&lt;/p&gt;
&lt;h3 id=&#34;partial-verdict-2&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Test structure: &lt;strong&gt;Spock wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;Spock cares more about well structured (and more readable) tests.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Btw, with both JUnit 5 and Spock it is worth to use &lt;a href=&#34;https://solidsoft.wordpress.com/2017/09/12/modern-tdd-oriented-java-8-junit-test-template-for-idea-with-mockito-and-assertj/&#34; target=&#34;_blank&#34;&gt;code templates&lt;/a&gt;
 to generate test skeleton to fill instead of writing all those given-when-then by hand :-).&lt;/p&gt;
&lt;h2 id=&#34;exception-testing&#34;&gt;Exception testing&lt;/h2&gt;
&lt;p&gt;Another topic I want to cover is exception testing. In general, to test corner cases (alternative scenarios) it is needed to verify that an exception with a given type was thrown. Usually, it is followed by some extra assertions such as an exception message and a cause.&lt;/p&gt;
&lt;h3 id=&#34;junit-5-1&#34;&gt;JUnit 5&lt;/h3&gt;
&lt;p&gt;In JUnit 5, it is no longer possible to use &lt;code&gt;@Test(expected = NullPointerException.class)&lt;/code&gt;, useful for one-liners, but potentially risky with more complicated test code. Instead of, we have the &lt;code&gt;assertThrows()&lt;/code&gt; construction, similar to &lt;code&gt;catchThrowable()&lt;/code&gt; from AssertJ.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldThrowBusinessExceptionOnCommunicationProblem&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//when
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Executable&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;sendPing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEST_REQUEST_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//then
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;CommunicationException&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;thrown&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;assertThrows&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommunicationException&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;assertEquals&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Communication problem when sending request with id: &amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TEST_REQUEST_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;
                 &lt;span class=&#34;n&#34;&gt;thrown&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getMessage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;());&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;assertEquals&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEST_REQUEST_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;thrown&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getRequestId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;());&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The syntax is very compact (thanks to the lambda expression which is used to catch an exception). In addition, it is easy to perform any required further assertion(s) on the returned exception instance.&lt;/p&gt;
&lt;h3 id=&#34;spock-1&#34;&gt;Spock&lt;/h3&gt;
&lt;p&gt;Spock, on the other hand, still provides &lt;code&gt;@FailsWith(NullPointerException)&lt;/code&gt; for one-liners. However, it is almost completely not used on a daily basis. All thanks to the &lt;code&gt;thrown()&lt;/code&gt; construction.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should capture exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;sendPing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEST_REQUEST_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;CommunicationException&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;thrown&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Communication problem when sending request with id: $TEST_REQUEST_ID&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;requestId&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TEST_REQUEST_ID&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It is worth to notice that there is no lambda expression to catch an exception. To implement that Spock leverages Groovy AST transformations which under the hood transparently add required code. As a result, the exception thrown in the &lt;code&gt;when&lt;/code&gt; block is caught and returned from the &lt;code&gt;thrown()&lt;/code&gt; method. Really smart.&lt;/p&gt;
&lt;p&gt;In addition, it is nice that in Spock, there is a smart type inference. It is not needed to precise the exception type twice. Based on the variable type on the left side, Spock is able to create the proper try-catch block.&lt;/p&gt;
&lt;p&gt;As a bonus, there as a separate utility class &lt;code&gt;Exceptions&lt;/code&gt; in Spock which provides extra assertions to play with the cause chain.&lt;/p&gt;
&lt;h3 id=&#34;partial-verdict-3&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Exception testing: &lt;strong&gt;Spock wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;Even shorter and less intrusive mechanism for exception testing.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;conditional-test-execution&#34;&gt;Conditional test execution&lt;/h2&gt;
&lt;p&gt;In multiple situation it is required to (not) execute a given test only if given condition is (not) met.&lt;/p&gt;
&lt;p&gt;The most common cases include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;particular Java version
&lt;ul&gt;
&lt;li&gt;reflection hack to use newer version features&lt;/li&gt;
&lt;li&gt;compatibility testing for lower version&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;specific operating system
&lt;ul&gt;
&lt;li&gt;notifications about changed files on Mac are much delayed&lt;/li&gt;
&lt;li&gt;testing symlinks on Windows makes no sense&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;tests executed only on CI server, stage environment, &amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;junit-5-2&#34;&gt;JUnit 5&lt;/h3&gt;
&lt;p&gt;JUnit 5 introduced brand new support for annotation-based &lt;code&gt;@Enabled*&lt;/code&gt; and &lt;code&gt;@Disabled*&lt;/code&gt; conditions.&lt;/p&gt;
&lt;p&gt;There is a predefined set of conditions for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JVM version&lt;/li&gt;
&lt;li&gt;operating system&lt;/li&gt;
&lt;li&gt;system property&lt;/li&gt;
&lt;li&gt;environment variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@DisabledOnOs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;WINDOWS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldTestSymlinksBasedLogic&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@EnabledIfSystemProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;named&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;os.arch&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;matches&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;.*32.*&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldBeRunOn32BitSystems&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The JVM version and operating system conditions are enums and thanks to that, there is a nice code completion provided by an IDE. In addition the conditions can be used as meta-annotations to make more complex scenarios easier to use in multiple places.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ElementType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;METHOD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@Retention&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RetentionPolicy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;RUNTIME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@EnabledOnOs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WINDOWS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@EnabledIfSystemProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;named&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;os.arch&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;matches&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;.*32.*&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@interface&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TestOn32BitWindows&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;With the following usage:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@TestOn32BitWindows&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldDoStrangeThings1OnLegacyWindows&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@TestOn32BitWindows&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldDoStrangeThings2OnLegacyWindows&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Originally, there was also support for custom logic in script-based inline conditions. However, due to limited usability (code written in &lt;code&gt;String&lt;/code&gt;) and deprecation of Nashorn in Java 11 it has been removed in JUnit 5.6. Writing own condition logic currently requires a custom implementation of &lt;code&gt;ExecutionCondition&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;spock-2&#34;&gt;Spock&lt;/h3&gt;
&lt;p&gt;Since time immemorial, Spock has provided support for annotation based conditions with &lt;code&gt;@Requires&lt;/code&gt; and &lt;code&gt;@IgnoreIf&lt;/code&gt;. Out of box it is possible to check:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JVM version&lt;/li&gt;
&lt;li&gt;operating system&lt;/li&gt;
&lt;li&gt;system property&lt;/li&gt;
&lt;li&gt;environment variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The same set implemented later on in JUnit 5. However, the usage is slightly different.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@IgnoreIf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jvm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;java8Compatible&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should return empty Optional by default for unstubbed methods with Java 8+&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@Requires&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;targetEnvironment&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;prod&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should execute smoke testing on non production environment&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Instead of enums, the logic is written in Groovy Closures leveraging delegation to the &lt;code&gt;jvm/os/sys/...&lt;/code&gt; objects providing a dedicated methods (such as &lt;code&gt;isJava11Compatible()&lt;/code&gt; or &lt;code&gt;isLinux()&lt;/code&gt;). Unfortunately there is no code completion available by default, but it can be enabled with a &lt;a href=&#34;https://speakerdeck.com/szpak/interesting-nooks-and-crannies-of-spock-you-may-have-never-seen-before?slide=27&#34; target=&#34;_blank&#34;&gt;small trick&lt;/a&gt;
 (Update. Just please be aware that the linked slides are from 2016 - Spock 1.0/1.1 - and in some places are outdated).&lt;/p&gt;
&lt;p&gt;Using Closures provides one more important benefit - custom logic can implemented inline with pure Groovy.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Requires&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;isStrongCryptographyEnabled&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//custom static method
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should test strong cryptography-based features&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;partial-verdict-4&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Conditional test execution: &lt;strong&gt;Spock wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;Higher flexibility with non standard conditions.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;mocking&#34;&gt;Mocking&lt;/h2&gt;
&lt;p&gt;Mocking is a crucial part of automatic code testing. It is especially beneficial in unit testing, but can be also usable in integration testing (e.g. with Spring Framework).&lt;/p&gt;
&lt;h3 id=&#34;junit-5-3&#34;&gt;JUnit 5&lt;/h3&gt;
&lt;p&gt;In JUnit 5 tests, Mockito is the first port of call when it comes to mocking.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;should_not_call_remote_service_if_found_in_cache&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//given
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;given&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cacheMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getCachedOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;willReturn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLUS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//when
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;checkOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//then
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;then&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;webserviceMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;never&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;checkOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//   verify(webserviceMock, never()).checkOperator(CACHED_MOBILE_NUMBER);   //alternative syntax
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Mockito is an industrial standard for mocking in Java. It is very mature, well known with a rich set of features. In addition, Spring Boot provides the official support for injecting Mockito&amp;rsquo;s mocks and spies into its context, which can be very useful in integration tests.&lt;/p&gt;
&lt;h3 id=&#34;spock-3&#34;&gt;Spock&lt;/h3&gt;
&lt;p&gt;Spock on the other hand contains a built-in mocking subsystem.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should not hit remote service if found in cache&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;given:&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cacheMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getCachedOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLUS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;checkOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;webserviceMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;checkOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;While the syntax in Mockito is pretty readable, there are all those &lt;code&gt;given/thenReturn/thenAnswer/...&lt;/code&gt; to write. Spock, however, leverages the power of operator overloading in Groovy (and of course its AST transformations) to make stubbing and verification as simple as possible.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;given&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cacheMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getCachedOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;willReturn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLUS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;));&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Mockito
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// vs
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cacheMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getCachedOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PLUS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Spock
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;verify&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;webserviceMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;never&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;checkOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Mockito
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// vs 
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;webserviceMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;checkOperator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CACHED_MOBILE_NUMBER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Spock
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In a basic case, it&amp;rsquo;s enough to write a method, use an operator and provide a returned value. In verification it&amp;rsquo;s just a method call with requested cardinality. Most likely, it will not be possible to achieve that in Java in the predictable future.&lt;/p&gt;
&lt;p&gt;Historically, the main limitation with Spock&amp;rsquo;s mocks was their tight coupling with the specification (the test itself). As a result it was not possible to use Spock&amp;rsquo;s stubs, mocks and spies in the Spring context for integration tests. However, starting with Spock 1.1 it was relaxed and Spock 1.2 introduced the first class &lt;a href=&#34;https://solidsoft.wordpress.com/2018/09/03/spock-1-2-hassle-free-spring-beans-mocking-in-integration-tests/&#34; target=&#34;_blank&#34;&gt;support&lt;/a&gt;
 for mocking and spying with Spring. As a bonus, it is available also for pure Spring context (Spring Boot is not required as it takes place with Mockito&amp;rsquo;s mocks).&lt;/p&gt;
&lt;p&gt;To be fair, it is required to admit that more &lt;em&gt;magic&lt;/em&gt; in Spock generates some &lt;a href=&#34;https://speakerdeck.com/szpak/interesting-nooks-and-crannies-of-spock-you-may-have-never-seen-before&#34; target=&#34;_blank&#34;&gt;quirks&lt;/a&gt;
 with some corner cases. Nevertheless, once knowing all of them the readability and compactness definitely pay off :-).&lt;/p&gt;
&lt;p&gt;One more thing. It is worth to remember that with Spock used for testing, we are not forced to use it also for mocking. It is perfectly fine to use Mockito if wanted (or needed).&lt;/p&gt;
&lt;h3 id=&#34;partial-verdict-5&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Mocking: &lt;strong&gt;Spock wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reason&lt;/strong&gt;: The syntax and really readable and compact. And with Spring support in Spock 1.2+ the last big limitation of the mocking subsystem in Spock was removed.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;parameterized-tests&#34;&gt;Parameterized tests&lt;/h2&gt;
&lt;p&gt;Parameterized tests in general provide a way to call one test with different set of input (and expected) parameters. It can dramatically reduce duplication in specific cases (e.g. in testing with the user defined acceptance data set).&lt;/p&gt;
&lt;p&gt;A word of warning here. In some scenarios, using parameterized tests can hide specific business use cases which would be clearly exposed in our non-parameterized tests otherwise. There are techniques to avoid that, but it is a topic for another article.&lt;/p&gt;
&lt;h3 id=&#34;junit-5-4&#34;&gt;JUnit 5&lt;/h3&gt;
&lt;p&gt;Parameterized tests were one of the key features of TestNG from its early days. In JUnit 4 the feature has been not available for year and even once implemented, the design made it very unpractical to use in most of the cases. To improve the situation the &lt;a href=&#34;https://github.com/Pragmatists/JUnitParams&#34; target=&#34;_blank&#34;&gt;3rd-party runners&lt;/a&gt;
 were available, but it was still sad (for JUnit 4).&lt;/p&gt;
&lt;p&gt;Luckily, JUnit 5 is the first version of JUnit with sane built-in parameterized tests support.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@ParameterizedTest&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@CsvSource&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;dog, 3&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;wolf, 4&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;hippopotamus , 12&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;testStringLengthWithParameterizedTestInJUnit5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;word&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedNumberOfLetters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;assertEquals&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;word&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedNumberOfLetters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;For simple scenario with inline values (provided as CSV strings), there is a nice implicit argument conversion from String for various types (e.g. dates, files, path or UUID). It just requires to add &lt;code&gt;@ParameterizedTest&lt;/code&gt; and &lt;code&gt;@CsvSource&lt;/code&gt; (or &lt;code&gt;@ValueSource&lt;/code&gt;, &lt;code&gt;@EnumSource&lt;/code&gt;, etc.).&lt;/p&gt;
&lt;p&gt;However, not everything can be put into string. The commonly encountered scenario is an object creation or calling a method defined in a test fixture. To support that JUnit 5 gives an ability to call a local method (or the one from external object) to return required input/output arguments. They should be provided as &lt;code&gt;Stream&lt;/code&gt; (or &lt;code&gt;List&lt;/code&gt;) of &lt;code&gt;Arguments&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@ParameterizedTest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;value to pay for invoice {0} should be {1}&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@MethodSource&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;invoiceProvider&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldCalculateToPayValueForInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Invoice&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;invoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BigDecimal&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedValueToPay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//when
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;valueToPay&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;invoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toPayValue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//expect
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;assertEquals&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expectedValueToPay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;valueToPay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Arguments&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;invoiceProvider&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;Arguments&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regularInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;54&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;Arguments&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;overduedInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;81&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;Arguments&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;paidInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It is just required to use &lt;code&gt;@MethodSource&lt;/code&gt; to point the method (or use a naming convention to resolve the correct method name automatically).&lt;/p&gt;
&lt;p&gt;The thing I don&amp;rsquo;t like is a lack of the arguments type check. In tests with multiple parameters it can be quite confusing to determine which is which.&lt;/p&gt;
&lt;p&gt;As a bonus it is also possible to customize a test name which will be displayed in the report (in IDE, HTML report, etc.).&lt;/p&gt;
&lt;h3 id=&#34;spock-4&#34;&gt;Spock&lt;/h3&gt;
&lt;p&gt;In Spock, first let&amp;rsquo;s take a longer look at the simple parameterized test.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Unroll&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should sum two integers (#x + #y = #expectedResult)&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
        &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calculator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedResult&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;    &lt;span class=&#34;nl&#34;&gt;where:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;         &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedResult&lt;/span&gt;
&lt;/span&gt;         &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;  &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The words that come to my mind are &amp;ldquo;state of the art&amp;rdquo;. This is a place where Spocks excels.&lt;/p&gt;
&lt;p&gt;With table-like formatting after the &lt;code&gt;where&lt;/code&gt; keyword, input data looks very natural and is easy to read. What is worth mentioning, there is no need to define &lt;code&gt;x, y, expectedResult&lt;/code&gt; as method arguments in a test (as it takes place in JUnit 5). The variables are added implicitly with full visibility and type inference in IDE.&lt;/p&gt;
&lt;p&gt;The method name can be parameterized inline with the &lt;code&gt;#var&lt;/code&gt; syntax (it&amp;rsquo;s Groovy - methods can have spaces and other &amp;ldquo;strange&amp;rdquo; characters).&lt;/p&gt;
&lt;p&gt;In Spock it is also not a problem to use table-like syntax in a situation where constructor or methods are needed to be called (which in JUnit 5 requires using a separate provider method).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Unroll&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Value to pay for invoice #invoice should be #expectedValueToPay&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should calculate value to pay for invoice&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;expect:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;invoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;valueToPay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedValueToPay&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;where:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;invoice&lt;/span&gt;           &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expectedValueToPay&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;regularInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;54&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;overduedInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;81&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;paidInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;     &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;While working with acceptance testing where results are presented to less technical users, it is also possible to distinguish a test name for developers with a scenario name for QA engineers (or product owners) by writing it in the &lt;code&gt;@Unroll&lt;/code&gt; annotation.&lt;/p&gt;
&lt;p&gt;Of course, for more complex/advanced use cases (e.g. generating input parameters dynamically based on exterenal source), data pipes and data providers can be used. They are not as natural as the aforementioned table, but are very powerful.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Unroll&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#pesel is valid (#dbId)&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should validate PESEL correctness (CSV)&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;expect:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;sut&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;validate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pesel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;where:&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dbId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pesel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;readValidPeopleFromCSVFile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;                                   &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;readLines&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;collect&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;                                   &lt;span class=&#34;c1&#34;&gt;//ugly way to read CSV - don&amp;#39;t do this :-)
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;partial-verdict-6&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Parameterized tests: &lt;strong&gt;Spock wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;It is enough to visually compare parameterized tests in those two frameworks.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;migration&#34;&gt;Migration&lt;/h2&gt;
&lt;p&gt;The next point is very important for people currently using JUnit 4.&lt;/p&gt;
&lt;h3 id=&#34;junit-4--junit-5&#34;&gt;JUnit 4 → JUnit 5&lt;/h3&gt;
&lt;p&gt;The JUnit 5 tests can co-exist with the JUnit 4 tests. There is a dedicated module &lt;code&gt;junit5-vintage&lt;/code&gt; which executes old JUnit 4 tests on the new JUnit Platform (part of JUnit 5).&lt;/p&gt;
&lt;p&gt;Writing new tests with JUnit 5 is also easy. The test structure is very similar. We just need to learn some new keywords, annotations and assertions (and remember to use &lt;code&gt;@Test&lt;/code&gt; from the new &lt;code&gt;org.junit.jupiter.api&lt;/code&gt; package :-) ).&lt;/p&gt;
&lt;h3 id=&#34;junit-4--spock&#34;&gt;JUnit 4 → Spock&lt;/h3&gt;
&lt;p&gt;The Spock tests can also co-exists with the JUnit 4 tests. In fact Spock 1.x is a (sophisticated, but still) JUnit 4 runner. However, besides that there is a completely new test structure which we need to get familiar with. It is easy to grasp and, in the end, it is more readable, but still, it is something new to learn.&lt;/p&gt;
&lt;h3 id=&#34;partial-verdict-7&#34;&gt;Partial verdict&lt;/h3&gt;
&lt;div class=&#34;alert alert-success&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;Tool support: &lt;strong&gt;JUnit 5 wins&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Reason: &lt;strong&gt;The JUnit 5 tests are more similar to the JUnit 4 tests and therefor, that migration path should be a little bit easier.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;One more important migration-related thing here. During my &lt;a href=&#34;https://blog.solidsoft.pl/training/&#34;&gt;training or consulting&lt;/a&gt;
, I do not recommend rewriting existing hundreds and thousands of tests from JUnit 4 to the new technology, just for fun. Most of the existing tests will stay untouched for the foreseeable future. It is much better to write the new tests in the new technology and rewrite existing tests only along the way of doing some production logic related changes in them.&lt;/p&gt;
&lt;h3 id=&#34;summary---final-verdict&#34;&gt;Summary - final verdict&lt;/h3&gt;
&lt;p&gt;Inarguably, JUnit 5 is a great progress over JUnit 4. Many features (previously) unique to Spock now are available in JUnit 5. However, Spock still excels in some areas. The best choice is no longer obvious.&lt;/p&gt;
&lt;p&gt;Here, an anecdote, proposed my a colleague of mine. There are BMW and Audi cars. Both brands are very good and the choice usually depends on our personal preferences.&lt;/p&gt;
&lt;p&gt;There same with Spock and JUnit 5. First, let&amp;rsquo;s take a look at the features comparison of the presented testing frameworks.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;JUnit 5 &lt;span class=&#34;table-smaller&#34;&gt;(as of 5.6)&lt;/span&gt;&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Spock &lt;span class=&#34;table-smaller&#34;&gt;(as of 1.3)&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;development&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good &lt;span class=&#34;table-smaller&#34;&gt;(new features and bugfixes)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;learning curve&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt; &lt;span class=&#34;table-smaller&#34;&gt;(similar to 4)&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good &lt;span class=&#34;table-smaller&#34;&gt;(Groovy to grasp)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tool support&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt; &lt;span class=&#34;table-smaller&#34;&gt;(trending up)&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good &lt;span class=&#34;table-smaller&#34;&gt;(weaker compile time checks)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;test structure&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt; &lt;span class=&#34;table-smaller&#34;&gt;(BDD by default)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;exception testing&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;conditional test execution&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt; &lt;span class=&#34;table-smaller&#34;&gt;(custom logic)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mocking&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good &lt;span class=&#34;table-smaller&#34;&gt;(Mockito)&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good+ &lt;span class=&#34;table-smaller&#34;&gt;(very compact, some quirks)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;parameterized tests&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;&lt;strong&gt;very good&lt;/strong&gt;&lt;/span&gt; &lt;span class=&#34;table-smaller&#34;&gt;(exceptional!)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;migration from JUnit 4&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;span style=&#34;color: green&#34;&gt;very good&lt;/span&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;good&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As you see, they both have their strengths and weaknesses. In addition to covered aspects, you should add to that list other aspects which are important for you (and for your team) and see which framework fits you more.&lt;/p&gt;
&lt;p&gt;For instance.&lt;/p&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;If you prefer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;old good Java as the only language&lt;/li&gt;
&lt;li&gt;stability and being mainstream&lt;/li&gt;
&lt;li&gt;stronger compile time error checking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;you should choose &lt;strong&gt;JUnit 5&lt;/strong&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;On the other hand,&lt;/p&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;if - like me - you favor:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;simplicity and readability&lt;/li&gt;
&lt;li&gt;power of Groovy under the hood&lt;/li&gt;
&lt;li&gt;beautiful parameterized tests and exception testing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&#34;alert-bigger&#34;&gt;then &lt;strong&gt;Spock&lt;/strong&gt; should be better for you.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;One final reflection. Preparing my presentation (and later on that blog post), I realized it would be great to have only that kind of dilemma while crafting software, choose between two pieces of good software :-).&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;A note about Spock logo. As of earthdate 2020-04, Spock doesn&amp;rsquo;t have the official logo. The one used in the lead photo is a proposal by &lt;a href=&#34;https://github.com/sbglasius&#34;&gt;Søren Berg Glasius&lt;/a&gt; made back in 2014. There are also &lt;a href=&#34;https://github.com/spockframework/spock/pull/34#issuecomment-586403638&#34;&gt;some&lt;/a&gt; other &lt;a href=&#34;https://github.com/spockframework/spock/pull/34#issuecomment-592687040&#34;&gt;proposals&lt;/a&gt;, but if you have a good idea, feel free to propose it &lt;a href=&#34;https://github.com/spockframework/spock/pull/34&#34;&gt;there&lt;/a&gt; (or vote for existing candidates).&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock-vs-junit5-ratio.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock-vs-junit5-ratio.png" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>spock</category>
            
          
            
              <category>junit5</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>java</category>
            
          
            
              <category>groovy</category>
            
          
            
              <category>presentation</category>
            
          
            
              <category>comparison</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
            
              <category>Deep Dive</category>
            
          
        
        
      </item>
      
      <item>
        <title>Places where you REALLY NEED to use &#39;assert&#39; keyword in Spock assertions</title>
        <link>https://blog.solidsoft.pl/2020/03/18/places-where-you-really-need-to-use-assert-keyword-in-spock-assertions/</link>
        <pubDate>Wed, 18 Mar 2020 10:00:00 +0200</pubDate>
        
        <atom:modified>Sun, 26 Dec 2021 23:50:00 +0100</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/03/18/places-where-you-really-need-to-use-assert-keyword-in-spock-assertions/</guid>
        <description>Make sure you know all the places where putting the &amp;lsquo;assert&amp;rsquo; keyword in Spock is necessary to avoid false sense of security and tests which - effectively - do nothing.
  Introduction Spock greatly simplifies test creation. One of the improvements is an ability to skip the assert keyword in the verification block (then or expect). It is very convenient, but Spock newcomers (and based on my code testing training also even more experienced developers) might not be aware that under some circumstances that keyword is required, making - as a result - that particular test useless.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Make sure you know all the places where putting the &amp;lsquo;assert&amp;rsquo; keyword in Spock is necessary to avoid false sense of security and tests which - effectively - do nothing.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/spock-assert-mandatory.png&#34; alt=&#34;TODO&#34; style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Spock greatly simplifies test creation. One of the improvements is an ability to skip the &lt;code&gt;assert&lt;/code&gt; keyword in the verification block (&lt;code&gt;then&lt;/code&gt; or &lt;code&gt;expect&lt;/code&gt;). It is very convenient, but Spock newcomers (and based on my &lt;a href=&#34;https://blog.solidsoft.pl/training/automatic-code-testing-java-spock-junit5/&#34;&gt;code testing training&lt;/a&gt;
 also even more experienced developers) might not be aware that under some circumstances that keyword is required, making - as a result - that particular test useless. After lecture of this blog post you will know the places (situations) where the &lt;code&gt;assert&lt;/code&gt; keyboard is mandatory.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start from the beginning.&lt;/p&gt;
&lt;h2 id=&#34;power-assertions&#34;&gt;Power assertions&lt;/h2&gt;
&lt;p&gt;Power assertions is an advanced assertion mechanism which renders the failed assertion in a very meaningful way. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;results in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;Assertion&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;failed:&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;     &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;
          &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;    &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;  &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;    &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;   &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a great step forward over the classic &lt;code&gt;assertEquals()&lt;/code&gt; assertion with just &lt;code&gt;Assertion failed&lt;/code&gt; in JUnit.&lt;/p&gt;
&lt;p&gt;What is nice, it works also for objects and method calls:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;Assertion&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;failed:&lt;/span&gt; 

&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ann&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bob&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ann&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bob&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;age&lt;/span&gt;
       &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;
       &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;Ann&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;Bob&lt;/span&gt;  &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
       &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;Person&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;name:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Bob&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;age:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
       &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;        &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;Person&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;name:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ann&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;age:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Power assertions have been developed initially for Spock, but later on they were backported to Groovy 1.7 (2009). Currently, they are one of the killer &lt;a href=&#34;https://groovy-lang.org/testing.html#_power_assertions&#34; target=&#34;_blank&#34;&gt;features of Groovy&lt;/a&gt;
 in the context of testing (in general, not only with Spock).&lt;/p&gt;
&lt;h2 id=&#34;optional-assert&#34;&gt;Optional &amp;lsquo;assert&amp;rsquo;&lt;/h2&gt;
&lt;p&gt;As I already mentioned in the introduction, Spock using the Groovy magic (primarily AST transformations and operator overloading) generates and automatically handles different aspect of tests to make its creation as simple as possible. Among others, it is visible in exception testing - a hidden &lt;code&gt;try..catch&lt;/code&gt; around the &lt;code&gt;when&lt;/code&gt; block or implicit method arguments in parameterized tests.&lt;/p&gt;
&lt;p&gt;Another case for simplification in an optional &lt;code&gt;assert&lt;/code&gt; keyword with assertions. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;nl&#34;&gt;expect:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;numberOfItems&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;can be simplified to just:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;nl&#34;&gt;expect:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;numberOfItems&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;assert&lt;/code&gt; keyword is automatically added by the Spock AST transformation in the &lt;code&gt;then&lt;/code&gt; or &lt;code&gt;expect&lt;/code&gt; blocks, if there is a boolean value, but also any non-void statement which can be evaluated with &lt;a href=&#34;https://groovy-lang.org/semantics.html#Groovy-Truth&#34; target=&#34;_blank&#34;&gt;The Groovy Truth&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;This opens different possibilities:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; 
&lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Invoiced&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;overdueInvoices&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;userAccount&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getOverdueIncoives&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;overdueInvoices&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//collection cannot be null or empty to not to fail
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Under the hood, the Spock AST transformation detects all those places to enhance them with &lt;code&gt;assert&lt;/code&gt;, but there are some limitations.&lt;/p&gt;
&lt;h2 id=&#34;required-assert&#34;&gt;Required &amp;lsquo;assert&amp;rsquo;&lt;/h2&gt;
&lt;div class=&#34;notices warning&#34; &gt;
  There are places (situations) where &lt;code&gt;assert&lt;/code&gt; cannot be omitted. It is especially crucial to know them as there is no error displayed. The assertions &lt;strong&gt;just do not work&lt;/strong&gt; which makes them useless. Or event worse, it &lt;strong&gt;gives a false sense of security&lt;/strong&gt; - those tests do not test anything.
&lt;/div&gt;
&lt;h3 id=&#34;guard-assertion&#34;&gt;Guard assertion&lt;/h3&gt;
&lt;p&gt;The first case is so-called guard assertion. Occasionally, mostly in integration/acceptance testing there is a need to check the initial state (e.g. number of records in a database to ensure than some previously added new - badly written - test did not break our test data).&lt;/p&gt;
&lt;p&gt;Spock cares only about &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;expect&lt;/code&gt; blocks in the context of the implicit &lt;code&gt;assert&lt;/code&gt;. The &lt;code&gt;assert&lt;/code&gt; keyword is not automatically added in the &lt;code&gt;given&lt;/code&gt; block and has to be placed manually.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nl&#34;&gt;given:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Invoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;initialInvoices&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legacyRepository&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getUserInvoices&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USER_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;initialInvoices&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//&amp;#39;assert&amp;#39; is mandatory - &amp;#39;initialInvoices.size() == 0&amp;#39; does nothing!
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;issueInvoice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(...)&lt;/span&gt;
&lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;legacyRepository&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getUserInvoices&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USER_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//&amp;#39;assert&amp;#39; is not needed in &amp;#39;then&amp;#39; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;assertion-in-method-execution&#34;&gt;Assertion in method execution&lt;/h3&gt;
&lt;p&gt;The another situation refers to the &lt;code&gt;then&lt;/code&gt; (or &lt;code&gt;expect&lt;/code&gt;) block. Sometimes there is a set of assertions that is used in more than one tests. It might be handy to extract them to a separate method (placed locally in the test class, in a super class, or in a trait):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;    &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;assertCompatibilityWithArticle17OfEUDirective&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;socialMediaSubmission&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;assertCompatibilityWithArticle17OfEUDirective&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SocialMediaSubmission&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;submission&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;submission&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;field1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//&amp;#39;assert&amp;#39; is mandatory 
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;submission&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;field2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For Spock, method call is treated as a regular value to be evaluated (if method is non-void). Therefore, if a method returns &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt; or an empty collection the test fails. Otherwise, also if a method has the &lt;code&gt;void&lt;/code&gt; return type, the test passes.&lt;/p&gt;
&lt;p&gt;It is requires to care about the assertions manually, but placing the &lt;code&gt;assert&lt;/code&gt; keyword explicitly withing the method.&lt;/p&gt;
&lt;h3 id=&#34;assertion-in-closure-execution&#34;&gt;Assertion in Closure execution&lt;/h3&gt;
&lt;p&gt;A similar class of problems poses assertions within closures. They might be not so often used as in methods, but it makes them even more at risk of incorrect usage.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;nl&#34;&gt;expect:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;GParsPool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withPool&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;eachParallel&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CorrelationIdUpdater&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;wrapClosureWithId&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//mandatory &amp;#34;assert&amp;#34;
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With Groovy 3 (and &lt;a href=&#34;https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/&#34;&gt;Spock 2.0-M2+&lt;/a&gt;
) the same applies to assertions in lambda expressions.&lt;/p&gt;
&lt;h3 id=&#34;other-cases&#34;&gt;Other cases&lt;/h3&gt;
&lt;p&gt;Quoting the &lt;a href=&#34;https://spockframework.org/spock/docs/2.0/all_in_one.html#_implicit_and_explicit_conditions&#34; target=&#34;_blank&#34;&gt;Spock documentation&lt;/a&gt;
:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Conditions are an essential ingredient of then blocks and expect blocks. Except for calls to void methods and expressions classified as interactions, all top-level expressions in these blocks are implicitly treated as conditions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, in addition to the 3 aforementioned cases, anything not &amp;ldquo;top-level&amp;rdquo; (or not placed in the &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;expect&lt;/code&gt; blocks) should bring our attention. That includes - less popular - conditional statements (&lt;code&gt;if/else&lt;/code&gt;), loops, and the &lt;code&gt;catch&lt;/code&gt; blocks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated 2021-12-26&lt;/strong&gt;. Added the &amp;ldquo;Other cases&amp;rdquo; section, based on a constructive comment by &lt;a href=&#34;https://github.com/szpak/blog.solidsoft.pl-comments/issues/7#issuecomment-994562701&#34; target=&#34;_blank&#34;&gt;Hari Krishna Dara&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Spock and Groovy (as every tool or language) can be used in more or less &amp;ldquo;messy way&amp;rdquo;. Groovy being a very flexible and optionally dynamic language makes it even easier. &amp;ldquo;With great power comes great responsibility&amp;rdquo;, a proverb popularized by the Spider-Man franchise, can be applied also to Spock. Users should be aware of the limitations and corner cases to avoid mistakes.&lt;/p&gt;
&lt;p&gt;Btw, in the context of assertions those are corner cases where assertion(-like) expression is just ignored, which is much worse than just an error. However, it is not the only place. A few years ago I made a 50-minutes long &lt;a href=&#34;https://blog.solidsoft.pl/talks/2016-06-01-nooks-and-crannies-of-spock-gr8conf/&#34;&gt;presentations&lt;/a&gt;
 just about &amp;ldquo;Interesting nooks and crannies of Spock&amp;rdquo; (&lt;a href=&#34;https://blog.solidsoft.pl/talks/2016-06-01-nooks-and-crannies-of-spock-gr8conf/&#34;&gt;slides and videos&lt;/a&gt;
). And definitely I didn&amp;rsquo;t exhausted a topic :-).&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo based on unofficial Spock logo &lt;a href=&#34;https://github.com/spockframework/spock/pull/34&#34;&gt;proposal&lt;/a&gt; from 2014 by &lt;a href=&#34;https://github.com/sbglasius&#34;&gt;Søren Berg Glasius&lt;/a&gt; and work safety signs by &lt;a href=&#34;https://pixabay.com/users/Clker-Free-Vector-Images-3736/&#34;&gt;Clker-Free-Vector-Images&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/vectors/eye-protection-mandatory-sign-24091/&#34;&gt;Pixabay&lt;/a&gt;.&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl//images/posts/2020/spock-assert-mandatory-thumbnail.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl//images/posts/2020/spock-assert-mandatory-ratio.png" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>spock</category>
            
          
            
              <category>pitfall</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>tests</category>
            
          
            
              <category>groovy</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>Migrating Spock 1.3 tests to Spock 2.0</title>
        <link>https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/</link>
        <pubDate>Thu, 02 Jan 2020 10:00:00 +0200</pubDate>
        
        <atom:modified>Wed, 11 Mar 2020 22:21:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/</guid>
        <description>Get know what you can expect from Spock 2.0 M2 (based on JUnit 5), how to migrate to it in Gradle and Maven, and why it is important to report spotted problems :).
 Important note. I definitely do not encourage you to migrate your serious real-life project to Spock 2.0 M1 or M2 for good! This is the first (pre-)release of 2.x with not finalized API, intended to gather user feedback related to internal Spock migration to JUnit Platform.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Get know what you can expect from Spock 2.0 M2 (based on JUnit 5), how to migrate to it in Gradle and Maven, and why it is important to report spotted problems :).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt;. I definitely do &lt;strong&gt;not&lt;/strong&gt; encourage you to migrate your serious real-life project to Spock 2.0 M1 or M2 for good! This is the first (pre-)release of 2.x with not finalized API, intended to gather user feedback related to internal Spock migration to JUnit Platform.&lt;/p&gt;
&lt;p&gt;This blog post arose to try to encourage you to make a &lt;strong&gt;test&lt;/strong&gt; migration of your projects to Spock 2.0, see what started to fail, fix it (if caused by your tests) or report it (if it is a regression in Spock itself). As a result - at the Spock side - it will be possible to improve the code base before Milestone 2. The benefit for you - in addition to contribution to the FOSS project :-) - will be awareness of required changes (kept in a side branch) and readiness to migration once Spock 2.0 is more mature.&lt;/p&gt;
&lt;p&gt;I plan to update this blog post when the next Spock 2 versions are available.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated 2020-02-10 to cover Spock 2.0 M2 with a dedicated Groovy 3 support.&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;Updated 2020-03-05&lt;/strong&gt;. New point about dealing with &lt;code&gt;NoClassDefFoundError: LambdaExpression&lt;/code&gt;.&lt;br /&gt;
&lt;strong&gt;Updated 2020-03-11&lt;/strong&gt;. Detecting &amp;ldquo;no tests&amp;rdquo; issue with multiple test tasks.&lt;/p&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/spock2-junit5-logo-grey-horiz.png&#34; alt=&#34;Spock 2 &amp;#43; JUnit 5 with Gradle and Maven&#34; style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;powered-by-junit-platform&#34;&gt;Powered by JUnit Platform&lt;/h2&gt;
&lt;p&gt;The main change in Spock 2.0 M1 is migration to JUnit 5 (precisely speaking to execute tests with JUnit Platform 1.5, part of JUnit 5 instead of the JUnit 4 runner API). This is very convenient as Spock tests should be automatically recognized and executed everywhere the JUnit Platform is supported (IDEs, build tools, quality tools, etc.). In addition, the features provided by the platform itself (such as parallel test execution) should be (eventually) available also for Spock.&lt;/p&gt;
&lt;h3 id=&#34;gradle&#34;&gt;Gradle&lt;/h3&gt;
&lt;p&gt;To bring Spock 2 to a Gradle project it is needed to bump the Spock version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and activate tests execution by JUnit Platform:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Update 20200218&lt;/strong&gt;. It is enough, but as Tomek Przybysz reminded in his comment, Gradle by default doesn&amp;rsquo;t fail if not tests are found. It may lead to a situation when after making that switch a build finished successfully, giving a false sense of security, while there are no tests executed at all.&lt;br /&gt;
It is a &lt;a href=&#34;https://github.com/gradle/gradle/issues/7452&#34; target=&#34;_blank&#34;&gt;known issue&lt;/a&gt;
 in Gradle, not only limited to Spock. As a workaround the aforementioned configuration might to extended to:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;afterSuite&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;testCount&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;No tests were found. Failing the build&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Or the more sophisticated version for multiple test tasks (e.g. unit/integration and functional):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Test&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configureEach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;testTask&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testTask&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configure&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;afterSuite&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;testCount&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
                    &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;No tests were found. Failing the build&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;maven&#34;&gt;Maven&lt;/h3&gt;
&lt;p&gt;With Maven on the other hand, it is still required to switch to a never Spock version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.spockframework&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spock-core&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0-M2-groovy-2.5&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but that is all. The Surefire plugin (if you use version 3.0.0+) executes JUnit Platform tests by default, if junit-platform-engine (a transitive dependency of Spock 2) is found.&lt;/p&gt;
&lt;p&gt;The minimal working project for Gradle i Maven is available from &lt;a href=&#34;https://github.com/szpak/code-examples-and-poc/tree/master/spock2-migration-gradle-maven&#34; target=&#34;_blank&#34;&gt;GitHub&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;other-changes&#34;&gt;Other changes&lt;/h2&gt;
&lt;p&gt;Having such big change as migration to JUnit Platform, number of other changes in Spock 2.0 M1 is limited, to make finding a reason of potential regressions a little bit easier. As a side effects of the migration itself, the required Java version is 8.&lt;/p&gt;
&lt;p&gt;In addition, all parameterized tests are (finally) &amp;ldquo;unrolled&amp;rdquo; automatically. That is great, however, currently there is &lt;a href=&#34;https://github.com/spockframework/spock/issues/967&#34; target=&#34;_blank&#34;&gt;no way&lt;/a&gt;
 to &amp;ldquo;roll&amp;rdquo; particular tests, as known from &lt;a href=&#34;https://github.com/szpak/spock-global-unroll&#34; target=&#34;_blank&#34;&gt;spock-global-unroll&lt;/a&gt;
 for Spock 1.x.&lt;/p&gt;
&lt;p&gt;Some other changes (such as temporarily disabled &lt;code&gt;SpockReportingExtension&lt;/code&gt;) can be found in the &lt;a href=&#34;https://github.com/spockframework/spock/blob/master/docs/release_notes.adoc#20-m1-31122019&#34; target=&#34;_blank&#34;&gt;release notes&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;More (possibly breaking) changes are expected to be merged into Milestone 2.&lt;/p&gt;
&lt;h2 id=&#34;issue-with-junit-4-rules&#34;&gt;Issue with JUnit 4 rules&lt;/h2&gt;
&lt;p&gt;The tests using JUnit 4 &lt;code&gt;@Rule&lt;/code&gt;s (or &lt;code&gt;@ClassRule&lt;/code&gt;s) are expected to fail with an error message suggesting that requested objects were not created/initialized before a test (e.g. &lt;code&gt;NullPointerException&lt;/code&gt; or &lt;code&gt;IllegalStateException: the temporary folder has not yet been created&lt;/code&gt;) or were not verified/cleaned up after it (e.g. soft assertions from AssertJ). The Rules API is no longer supported by JUnit Platform. However, to make the migration easier (&lt;code&gt;@TemporaryFolder&lt;/code&gt; is probably very often used in Spock-based integration tests), there is a dedicated &lt;code&gt;spock-junit4&lt;/code&gt; which internally wraps JUnit 4 rules into the Spock extensions and executes it in the Spock&amp;rsquo;s lifecycle. As it is implemented as a global extension, the only required thing to add is another dependency. In Gradle:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-junit4:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or in Maven:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.spockframework&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spock-junit4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0-M2-groovy-2.5&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That makes migration easier, but it is good to think about a switch to native Spock counterpart, if available/feasible.&lt;/p&gt;
&lt;h2 id=&#34;groovy-3-support&#34;&gt;Groovy 3 support&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Updated 2020-02-10&lt;/strong&gt;. The whole Groovy 3 section was added to cover changes in Spock 2.0 Milestone 2.&lt;/p&gt;
&lt;p&gt;After my complains about runtime failure when Spock 2.0 M1 is used with Groovy 3.0, I rolled up my sleeves to check how hard would it be to provide that support. It took me some time, however, after after &lt;a href=&#34;https://github.com/spockframework/spock/pull/1075&#34; target=&#34;_blank&#34;&gt;23 (multiple times rebased) commits&lt;/a&gt;
, constructive feedback from other Spock contributors and fruitful discussion with the Groovy developers, the support for Groovy 3 has been merged and is available as the main feature of Spock 2.0 M2, released right after Groovy 3.0.0 final.&lt;/p&gt;
&lt;p&gt;To use Spock 2.0 M2 with Groovy 3 it is enough to just use the &lt;code&gt;spock-*-2.0-M1&lt;/code&gt; artifacts with the &lt;code&gt;-groovy-3.0&lt;/code&gt; suffix.&lt;/p&gt;
&lt;p&gt;It is worth noting that Groovy 3 is not backward compatible with Groovy 2. To keep one Spock codebase, there is a layer of abstraction in Spock to allow to build (and use) the project with both Groovy 2 and 3. As a result, an extra artifact &lt;code&gt;spock-groovy2-compat&lt;/code&gt; is (automatically) used in projects with Groovy 2. It is &lt;strong&gt;very important&lt;/strong&gt; to &lt;strong&gt;do not mix&lt;/strong&gt; the &lt;code&gt;spock-*-2.x-groovy-2.5&lt;/code&gt; artifacts with the &lt;code&gt;groovy-*-3.x&lt;/code&gt; artifacts on a classpath. This may result in weird runtime errors.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m really happy that developers can immediately start testing the new Groovy 3.0.0 with Spock 2.0-M2 in their projects. In addition, as Spock is quite important (and low level) project in the Groovy ecosystem, it was nice to confirm that Groovy 3 works properly with it (and to report - along the way - a few minor detected issues to make Groovy even better ;-) ).&lt;/p&gt;
&lt;h2 id=&#34;other-issues-and-limitations&#34;&gt;Other issues and limitations&lt;/h2&gt;
&lt;h3 id=&#34;noclassdeffounderror-lambdaexpression-with-groovy-25&#34;&gt;NoClassDefFoundError: LambdaExpression with Groovy 2.5&lt;/h3&gt;
&lt;p&gt;Using Spock 2.0-M2 with Groovy 2.5 it is possible to get the following errors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java.lang.NoClassDefFoundError: org/codehaus/groovy/ast/expr/LambdaExpression
java.lang.NoClassDefFoundError: org/codehaus/groovy/ast/expr/MethodReferenceExpression
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As Groovy 2 and 3 are not backward compatible, there is an abstraction layer which allows to build (and use) Spock with two different Groovy versions. However, to achieve that it was necessary to add dummy &lt;code&gt;LambdaExpression&lt;/code&gt; and &lt;code&gt;MethodReferenceExpression&lt;/code&gt; in an extra Spock dependency &lt;code&gt;spock-groovy2-compat&lt;/code&gt; used in the &lt;code&gt;-groovy-2.5&lt;/code&gt; variant.&lt;/p&gt;
&lt;p&gt;It is automatically fetched by Maven/Gradle for &lt;code&gt;spock-core&lt;/code&gt;, but in the situation you disabled transitive dependency for Spock:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;transitive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Grab&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5;transitive=false&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;they are missing. In that case you might want to add &lt;code&gt;spock-groovy2-compat&lt;/code&gt; dependency explicitly, e.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;transitive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-groovy2-compat:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or exclude just Groovy dependencies (not all of them):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;exclude&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;group:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.codehaus.groovy&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Thanks to &lt;a href=&#34;https://twitter.com/paulk_asert&#34; target=&#34;_blank&#34;&gt;Paul King&lt;/a&gt;
 for suggesting that point.&lt;/p&gt;
&lt;h3 id=&#34;missing-groovy-3-support&#34;&gt;&lt;del&gt;Missing Groovy 3 support&lt;/del&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Updated 2020-02-10&lt;/strong&gt;. This section originally refereed to limitations of Spock 2.0 M1. Milestone 2 supports Groovy 3.&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;&lt;p&gt;Spock 2.0 M1 is compiled and tested only with Groovy 2.5.8. As of M1, execution with Groovy 3.0 is currently blocked at runtime. Unfortunately, instead of a clear error message about incompatible Groovy version there is only a very cryptic error message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at
jar:file:/.../spock-core-2.0-M1-groovy-2.5.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
because of exception java.lang.reflect.InvocationTargetException
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is already &lt;a href=&#34;https://github.com/spockframework/spock/issues/1067&#34;&gt;reported&lt;/a&gt; and should be enhanced by M2.&lt;/p&gt;
&lt;/span&gt;
&lt;div class=&#34;expand&#34;&gt;
  &lt;button type=&#34;button&#34; class=&#34;expand__button&#34; aria-label=&#34;Expand Button&#34;&gt;
    &lt;span class=&#34;expand-icon expand-icon__right&#34;&gt;
        &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M9.29 15.88L13.17 12 9.29 8.12c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0l4.59 4.59c.39.39.39 1.02 0 1.41L10.7 17.3c-.39.39-1.02.39-1.41 0-.38-.39-.39-1.03 0-1.42z&#34;/&gt;&lt;/svg&gt;
    &lt;/span&gt;
    Click here to expand outdated information about lack of Groovy 3 support in Spock 2.0-M1
  &lt;/button&gt;
  &lt;div class=&#34;expand__content&#34;&gt;
    &lt;span style=&#34;opacity: 0.6&#34;&gt;Sadly, the limitation to Groovy 2.5 only, reduces potential feedback from people experimenting with Groovy 3 which is pretty close to a stable version (RC2 as of 2019/2020). It’s especially inconvenient as many Spock tests just work with Groovy 3 (of course there are some corner cases). There is a chance that Spock 2 before getting final will be adjusted to changes in Groovy 3 or at least the aforementioned hard limitation will be lifted. In the meantime, it is required to test Groovy 3 support with the snapshot version - &lt;code&gt;2.0-groovy-2.5-SNAPSHOT&lt;/code&gt; (which has that check disabled).&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The action to do after reading this post is simple. Try to &lt;em&gt;temporarily&lt;/em&gt; play with Spock 2.0 M2 in your projects and &lt;a href=&#34;https://github.com/spockframework/spock/issues&#34; target=&#34;_blank&#34;&gt;report&lt;/a&gt;
 any spotted issues, to help make Spock 2.0 even better :).&lt;/p&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock2-junit5-logo-grey-horiz.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock2-junit5-logo-grey-horiz-ratio.png" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>gradle</category>
            
          
            
              <category>junit5</category>
            
          
            
              <category>maven</category>
            
          
            
              <category>migration</category>
            
          
            
              <category>spock</category>
            
          
            
              <category>spock2</category>
            
          
            
              <category>spock-2.0</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>tests</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>Simplify integration testing of legacy applications with Spock 1.2</title>
        <link>https://blog.solidsoft.pl/2018/09/14/simplify-integration-testing-of-legacy-applications-with-spock-1.2/</link>
        <pubDate>Fri, 14 Sep 2018 10:00:00 +0200</pubDate>
        
        <atom:modified>Fri, 14 Sep 2018 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2018/09/14/simplify-integration-testing-of-legacy-applications-with-spock-1.2/</guid>
        <description>Learn how leverage Spock 1.2 to slice a Spring context of a legacy application writing integration tests.
 Have you ever wanted, having some legacy application which you were starting to work on, to write some tests to get know what is going on and possibly be notified about regressions? That feeling when you want to instantiate a single class and it fails with NullPointerException. 6 replaced (with difficulty) dependencies later there are still some errors from the classes that you haven&amp;rsquo;t heard about before.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Learn how leverage Spock 1.2 to slice a Spring context of a legacy application writing integration tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Have you ever wanted, having some legacy application which you were starting to work on, to write some tests to get know what is going on and possibly be notified about regressions? That feeling when you want to instantiate a single class and it fails with &lt;code&gt;NullPointerException&lt;/code&gt;. 6 replaced (with difficulty) dependencies later there are still some errors from the classes that you haven&amp;rsquo;t heard about before. Sounds familiar?&lt;/p&gt;
&lt;p&gt;There are different techniques to deal with hidden dependencies. There is the whole dedicated &lt;a href=&#34;https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052&#34; target=&#34;_blank&#34;&gt;book&lt;/a&gt;
 about that (and probably a few other that I haven&amp;rsquo;t read). Occasionally, it may be feasible to start with the integration tests and run through some process. It may be even more &amp;ldquo;entertaining&amp;rdquo; to see what exotic components are required to just setup the context, even if they are completely not needed in our case. Thank you (too wide and carelessly used) &lt;code&gt;@ComponentScan&lt;/code&gt; :).&lt;/p&gt;
&lt;p&gt;Injecting stubs/mocks inside the test context is a way to go as an emergency assistance (see the last paragraph, there are better, yet harder approaches). It can be achieved &amp;ldquo;manually&amp;rdquo; with an extra bean definition with the &lt;code&gt;@Primary&lt;/code&gt; annotation (usually a reason to think twice before doing that) for every dependency at which level we want to make a cut of (or for every unneeded bean which is instantiated by the way). &lt;code&gt;@MockBean&lt;/code&gt; placed on a field in a test is more handy, but still, it is needed to define a field in our tests and put the annotation on it (5? 10? 15 beans?). Spock 1.2 introduces somehow less know feature which may be useful here - &lt;code&gt;@StubBeans&lt;/code&gt;.&lt;/p&gt;




  



  &lt;div class=&#34;featured-image__wrapper&#34;&gt;
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2018/mocked-dependencies-spring.png&#34; alt=&#34;Featured Image&#34; class=&#34;featured-image&#34; style=&#34;width: 680px;height: 356px;&#34;&gt;
  &lt;/div&gt;

&lt;p&gt;It can be used to simply provide a list of classes which (possible) instances should be replaced with stubs in the Spring test context. Of course before the real objects are being instantiated (to prevent for example NPE in a constructor). Thanks to that up to several lines of stubbing/mock injections:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@RunWith&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SpringRunner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Spring Boot + Mockito
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@SpringBootTest&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//possibly some Spring configuration with @ComponentScan is imported in this legacy application
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BasicPathReportGeneratorInLegacyApplicationITTest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//usual approach
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaClient&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;kafkaClientMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FancySelfieEnhancer&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fancySelfieEnhancerMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastTwitterSubscriber&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fastTwitterSubscriberMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WaterCoolerWaterLevelAterter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;waterCoolerWaterLevelAterterMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NsaSilentNotifier&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nsaSilentNotifierMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;//a few more - remember, this is legacy application, genuine since 1999 ;)
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ReportGenerator&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reportGenerator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldGenerateEmptyReportForEmptyInputData&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;can be replaced with just one (long) line:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@SpringBootTest&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//possibly some Spring configuration with @ComponentScan is imported
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@StubBeans&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;KafkaClient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FancySelfieEnhancer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastTwitterSubscriber&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WaterCoolerWaterLevelAterter&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NsaSilentNotifier&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/(, ... */&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;//all classes of real beans which should be replaced with stubs
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BasicPathReportGeneratorInLegacyApplicationITSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ReportGenerator&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reportGenerator&lt;/span&gt;

    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should generate empty report for empty input data&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;....&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;(tested with Spock 1.2-RC2)&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth to mention that &lt;code&gt;@StubBeans&lt;/code&gt; is intended just to provide placeholders. In a situation it is required to provide stubbing and/or an invocation verification &lt;code&gt;@SpringBean&lt;/code&gt; or &lt;code&gt;@SpringSpy&lt;/code&gt; (also introduced in Spock 1.2) are better. I wrote more about it in my previous &lt;a href=&#34;https://solidsoft.wordpress.com/2018/09/03/spock-1-2-hassle-free-spring-beans-mocking-in-integration-tests/&#34; target=&#34;_blank&#34;&gt;blog post&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There is one important aspect to emphasize&lt;/strong&gt;. &lt;code&gt;@StubBeans&lt;/code&gt; are handy to be used in a situation when we have some &amp;ldquo;legacy&amp;rdquo; project and want to start writing integration regression tests quickly to see the results. However, as a colleague of mine &lt;a href=&#34;https://stackoverflow.com/users/719633/roadrunner&#34; target=&#34;_blank&#34;&gt;Darek Kaczyński&lt;/a&gt;
 brightly summarized, blindly replacing beans which &amp;ldquo;explode&amp;rdquo; in tests is just &amp;ldquo;sweeping problems under carpet&amp;rdquo;. After the initial phase, when we are starting to understand what is going on, it is a good moment to rethink the way the context - both in production and in tests - is created. The already mentioned too wide &lt;code&gt;@ComponentScan&lt;/code&gt; is very often the root of all evil. An ability to setup a partial context and put it together (if needed) is a good place to start. Using &lt;code&gt;@Profile&lt;/code&gt; or conditional beans are the very powerful mechanisms in tests (and not only there). &lt;code&gt;@TestConfiguration&lt;/code&gt; and proper bean selection to improve context caching are something worth to keep in your mind. However, I started this article to present the new mechanism in Spock which might be useful in some cases and I want to keep it short. There could be an another, more generic blog post just about managing the Spring context in the integration tests. I have to seriously thing about it :).&lt;/p&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2018/mocked-dependencies-spring.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>groovy</category>
            
          
            
              <category>integration-testing</category>
            
          
            
              <category>mocking</category>
            
          
            
              <category>mockito</category>
            
          
            
              <category>spock</category>
            
          
            
              <category>spock-1.2</category>
            
          
            
              <category>spring</category>
            
          
            
              <category>spring-boot</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>tests</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
            
              <category>Tricks &amp; Tips</category>
            
          
        
        
      </item>
      
      <item>
        <title>Spock 1.2 - hassle-free Spring beans mocking in integration tests</title>
        <link>https://blog.solidsoft.pl/2018/09/03/spock-1.2-hassle-free-spring-beans-mocking-in-integration-tests/</link>
        <pubDate>Mon, 03 Sep 2018 10:00:00 +0200</pubDate>
        
        <atom:modified>Mon, 03 Sep 2018 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2018/09/03/spock-1.2-hassle-free-spring-beans-mocking-in-integration-tests/</guid>
        <description>Discover how to automatically inject Spock&amp;rsquo;s mocks and spies into the Spring context using Spock 1.2.
  Stubs/mocks/spies in Spock (and their life cycle) have been always tightly coupled with the Spock Specification class. It was only possible to create them in a test class. Therefore, using shared, predefined mocks (in both unit and integration tests) was problematic.
The situation was slightly improved in Spock 1.1, but only with the brand new Spock 1.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Discover how to automatically inject Spock&amp;rsquo;s mocks and spies into the Spring context using Spock 1.2.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2018/spock12-spring-bean-mocking960-ratio.jpg&#34; alt=&#34;A lot of coffee beans with a partially filled cup laying on it. 3 beans in a cup have different color&#34; style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;br&gt;
&lt;p&gt;Stubs/mocks/spies in Spock (and their life cycle) have been always tightly coupled with the Spock &lt;code&gt;Specification&lt;/code&gt; class. It was only possible to create them in a test class. Therefore, using shared, predefined mocks (in both unit and integration tests) was problematic.&lt;/p&gt;
&lt;p&gt;The situation was slightly improved in Spock 1.1, but only with the brand new Spock 1.2 (1.2-RC1 as a time of writing) using the Spock mocking subsystem in Spring-based integration tests is as easy as using &lt;code&gt;@SpringMock&lt;/code&gt; for Mockito mocks in Spring Boot. Let&amp;rsquo;s check it up.&lt;/p&gt;
&lt;p&gt;Btw, to be more cutting edge in addition to Spock 1.2-RC1, I will be using Spring Boot 2.1.0.M2, Spring 5.1.0.RC2 and Groovy 2.5.2 (but everything should work with the stable versions of Spring (Boot) and Groovy 2.4).&lt;/p&gt;
&lt;p&gt;One more thing. For the sake of simplicity, in this article, I will be using a term &amp;lsquo;mock&amp;rsquo; to refer also stubs and spies. They &lt;a href=&#34;https://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs&#34; target=&#34;_blank&#34;&gt;differs&lt;/a&gt;
 in behavior, however, in a scope of injecting it into the Spring context in the Spock tests it usually doesn&amp;rsquo;t matter.&lt;/p&gt;
&lt;h2 id=&#34;spock-11---manual-way&#34;&gt;Spock 1.1 - manual way&lt;/h2&gt;
&lt;p&gt;Thanks to the work of &lt;a href=&#34;https://github.com/leonard84&#34; target=&#34;_blank&#34;&gt;Leonard Brünings&lt;/a&gt;
, mocks in Spock were decoupled from the &lt;code&gt;Specification&lt;/code&gt; class. It was finally possible to create them outside and to attach it later on into a running test. It was the cornerstone of using Spock mocks in the Spring (or any other) context.&lt;/p&gt;
&lt;p&gt;In this sample code we have the &lt;code&gt;ShipDatabase&lt;/code&gt; class which uses &lt;code&gt;OwnShipIndex&lt;/code&gt; and &lt;code&gt;EnemyShipIndex&lt;/code&gt; (of course injected by a constructor :) ) to return aggregated information about all known ships matched by name.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//@ContextConfiguration just for simplification, @(Test)Configuration is usually more convenient for Spring Boot tests
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//Real beans can exist in the context or not
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@ContextConfiguration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;classes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ShipDatabase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TestConfig&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/*, OwnShipIndex, EnemyShipIndex*/&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ShipDatabase11ITSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;

    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ENTERPRISE_D&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;USS Enterprise (NCC-1701-D)&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BORTAS_ENTERA&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;IKS Bortas Entera&amp;#34;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OwnShipIndex&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ownShipIndexMock&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EnemyShipIndex&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enemyShipIndexMock&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ShipDatabase&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shipDatabase&lt;/span&gt;

    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should find ship in both indexes&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;given:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;ownShipIndexMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findByName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Enter&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENTERPRISE_D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;enemyShipIndexMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findByName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Enter&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BORTAS_ENTERA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;foundShips&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shipDatabase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findByName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Enter&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;foundShips&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENTERPRISE_D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BORTAS_ENTERA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;//    @TestConfiguration
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;TestConfig&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DetachedMockFactory&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;detachedMockFactory&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DetachedMockFactory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;nd&#34;&gt;@Bean&lt;/span&gt;
        &lt;span class=&#34;nd&#34;&gt;@Primary&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//if needed, beware of consequences
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;OwnShipIndex&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ownShipIndexStub&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;detachedMockFactory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;Stub&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OwnShipIndex&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

        &lt;span class=&#34;nd&#34;&gt;@Bean&lt;/span&gt;
        &lt;span class=&#34;nd&#34;&gt;@Primary&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//if needed, beware of consequences
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;EnemyShipIndex&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;enemyShipIndexStub&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;detachedMockFactory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;Stub&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EnemyShipIndex&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The mocks are created in a separate class (outside the &lt;code&gt;Specification&lt;/code&gt;) and therefore &lt;code&gt;DetachedMockFactory&lt;/code&gt; has to be used (or alternatively &lt;code&gt;SpockMockFactoryBean&lt;/code&gt;). Those mocks have to be attached (and detached) to the test instance (the &lt;code&gt;Specification&lt;/code&gt; instance), but it is automatically handled by the &lt;code&gt;spock-spring&lt;/code&gt; module (as of 1.1). For generic mocks created externally also &lt;code&gt;MockUtil.attachMock()&lt;/code&gt; and &lt;code&gt;mockUtil.detachMock()&lt;/code&gt; would need to be used to make it work.&lt;/p&gt;
&lt;p&gt;As a result it was possible to create and use mocks in the Spring context, but it was not very convenient and it was not commonly used.&lt;/p&gt;
&lt;h2 id=&#34;spock-12---first-class-support&#34;&gt;Spock 1.2 - first class support&lt;/h2&gt;
&lt;p&gt;Spring Boot 1.4 brought the new quality to integration testing with (Mockito&amp;rsquo;s) mocks. It leveraged the idea, originally presented in &lt;a href=&#34;https://github.com/springockito/springockito/&#34; target=&#34;_blank&#34;&gt;Springockito&lt;/a&gt;
 back in 2012 (when the Spring configuration was mostly written in XML :) ) to automatically inject mocks (or spies) into the Spring (Boot) context. The Spring Boot team extended the idea and thanks to having it as the internally supported feature it (usually) works reliably just by adding an annotation or two in your test.&lt;/p&gt;
&lt;p&gt;Similar annotation-based mechanism is built-in in Spock &lt;a href=&#34;https://search.maven.org/search?q=g:org.spockframework%20AND%20a:spock-core&amp;amp;core=gav&#34; target=&#34;_blank&#34;&gt;1.2&lt;/a&gt;
.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//@ContextConfiguration just for simplification, @(Test)Configuration is usually more convenient for Spring Boot tests
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//Real beans can exist in the context or not
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@ContextConfiguration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;classes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ShipDatabase&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/*, OwnShipIndex, EnemyShipIndex*/&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ShipDatabaseITSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;

    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ENTERPRISE_D&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;USS Enterprise (NCC-1701-D)&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BORTAS_ENTERA&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;IKS Bortas Entera&amp;#34;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@SpringBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OwnShipIndex&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ownShipIndexMock&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Stub&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//could be Mock() if needed
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@SpringBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EnemyShipIndex&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enemyShipIndexMock&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Stub&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ShipDatabase&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shipDatabase&lt;/span&gt;

    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should find ship in both indexes&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;given:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;ownShipIndexMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findByName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Enter&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENTERPRISE_D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;enemyShipIndexMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findByName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Enter&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BORTAS_ENTERA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;foundShips&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shipDatabase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findByName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Enter&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;foundShips&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENTERPRISE_D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BORTAS_ENTERA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;There is not much to be added. &lt;code&gt;@SpringBean&lt;/code&gt; instructs Spock to inject a mock into a Spring context. Similarly, &lt;code&gt;@SpringSpy&lt;/code&gt; wraps the real bean with a spy. In a case of &lt;code&gt;@SpringBean&lt;/code&gt; it is required to initialize a field to let Spock know if we plan to use a stub or a mock.&lt;/p&gt;
&lt;p&gt;In addition, there is also a more general annotation &lt;code&gt;@StubBeans&lt;/code&gt; to replace all defined beans with stubs. However, I plan to cover it separately in an another blog post.&lt;/p&gt;
&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;p&gt;For those of you who look forward to rewrite all Mockito&amp;rsquo;s mocks to Spock&amp;rsquo;s mocks in your Spock tests right after the lecture of this article there is a word of warning. Spock&amp;rsquo;s mocks - due to their nature and relation to &lt;code&gt;Specification&lt;/code&gt; - have some limitations. The implementation under the hood creates a proxy which is injected into the Spring context which (potentially) replaces real beans (stubs/mocks) or wraps them (spies). That proxy is shared between all the tests in the particular test (specification) class. In fact, it also can span across other tests with the same bean/mock declarations in the situation Spring is able to cache the context (similar situation to Mockito&amp;rsquo;s mocks or Spring integration tests in general).&lt;/p&gt;
&lt;p&gt;However, what is really important, a proxy is attached to a tests right before its execution and is detached right after it. Therefore, in fact, every test has it&amp;rsquo;s own mock instance (it cannot be applied to &lt;code&gt;@Shared&lt;/code&gt; fields) and it is problematic for instance to group interactions from different tests and verify them together (which usually is quite sensible, but might lead to some duplication). Nevertheless, with using a &lt;code&gt;setup&lt;/code&gt; block (or in-line stubbing) it is possible to share stubbing and interaction expectancy.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Spock 1.2 finally brings hassle-free Spock&amp;rsquo;s stubs/mocks/spies support for using them in the Spring context which is comparable with the one provided in Spring Boot for Mockito. It is just enough to add the &lt;code&gt;spock-spring&lt;/code&gt; module to the project (runtime) dependencies. Despite some limitations, it is one point less for mixing native Spock&amp;rsquo;s mocking subsystem with external mocking frameworks (such as Mockito) in your Spock (integration) tests. And what is nice, it should work also in plain Spring Framework tests (not only Spring Boot tests). The same feature has been implemented for Guice (but I haven&amp;rsquo;t tested it).&lt;/p&gt;
&lt;p&gt;Furthermore, Spock 1.2 brings also some other &lt;a href=&#34;https://github.com/spockframework/spock/blob/master/docs/release_notes.adoc&#34; target=&#34;_blank&#34;&gt;changes&lt;/a&gt;
 including better support for Java 9+ and it is worth to give it a try in your test suite (and of course &lt;a href=&#34;https://github.com/spockframework/spock/issues&#34; target=&#34;_blank&#34;&gt;report&lt;/a&gt;
 any potentially spotted regression bugs :) ).&lt;/p&gt;
&lt;p&gt;One more good news. In addition to the Leonard&amp;rsquo;s work who made Spock 1.2 possible and a legion of bug reporters and PR contributors, since recently, there are also some other committers who are working on making Spock even better. Some of them you may know from some other popular FOSS projects. What is more, Spock 1.2 is &lt;em&gt;(preliminary) planned&lt;/em&gt; to be the last version based on JUnit 4 and the next stable Spock version could be 2.0, leveraging JUnit 5 and (among others) its native ability to run tests in parallel.&lt;/p&gt;
&lt;p&gt;The examples were written using Spock 1.2-RC1. It will be updated to 1.2-final once released. The source code is available from GitHub.&lt;/p&gt;
&lt;p&gt;Btw, have you wonder if it is still worth using Spock in the time of JUnit 5? I try to help answer that question in my presentation which will be possible to &lt;a href=&#34;https://jdd.org.pl/lecture.html#id=47734&#34; target=&#34;_blank&#34;&gt;see&lt;/a&gt;
 at &lt;a href=&#34;https://jdd.org.pl/&#34; target=&#34;_blank&#34;&gt;JDD 2018&lt;/a&gt;
, this October in Kraków, Poland. See you there.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://jdd.org.pl/lecture.html#id=47734&#34; target=&#34;_blank&#34;&gt;

&lt;figure &gt;
  
    &lt;img data-src=&#34;https://blog.solidsoft.pl/images/posts/2018/jdd2018-logo-with-date.png&#34; alt=&#34;JDD 2018 logo with date&#34; data-caption=&#34;&#34; src=&#34;data:image/svg+xml,%0A%3Csvg xmlns=&#39;http://www.w3.org/2000/svg&#39; width=&#39;614px&#39; height=&#39;204&#39; viewBox=&#39;0 0 24 24&#39;%3E%3Cpath fill=&#39;none&#39; d=&#39;M0 0h24v24H0V0z&#39;/%3E%3Cpath fill=&#39;%23aaa&#39; d=&#39;M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z&#39;/%3E%3C/svg%3E&#34; class=&#34;lazyload&#34; style=&#34;width:614px;height:204;&#34;/&gt;
    
  
&lt;/figure&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;The lead photo based on the &lt;a href=&#34;https://pixabay.com/en/users/Couleur-1195798/&#34;&gt;Couleur&lt;/a&gt;&amp;lsquo;s &lt;a href=&#34;https://pixabay.com/en/coffee-beans-coffee-cup-cup-coffee-3392159/&#34;&gt;work&lt;/a&gt; published in &lt;a href=&#34;https://pixabay.com/&#34;&gt;Pixabay&lt;/a&gt;, &lt;a href=&#34;https://creativecommons.org/publicdomain/zero/1.0/deed.en&#34;&gt;CC0 1.0&lt;/a&gt;&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2018/spock12-spring-bean-mocking960.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>mocking</category>
            
          
            
              <category>spock</category>
            
          
            
              <category>spock-1.2</category>
            
          
            
              <category>spring</category>
            
          
            
              <category>spring-boot</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>tests</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      

    
  </channel>
</rss>