<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Roland Weisleder</title>
    <description>The latest articles on Forem by Roland Weisleder (@rweisleder).</description>
    <link>https://forem.com/rweisleder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F938162%2F95bf74d7-514c-419f-890c-7ed4823f7057.jpeg</url>
      <title>Forem: Roland Weisleder</title>
      <link>https://forem.com/rweisleder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rweisleder"/>
    <language>en</language>
    <item>
      <title>Refactoring Legacy Code: Can We Trust Existing Tests?</title>
      <dc:creator>Roland Weisleder</dc:creator>
      <pubDate>Fri, 01 Mar 2024 08:43:22 +0000</pubDate>
      <link>https://forem.com/rweisleder/refactoring-legacy-code-can-we-trust-existing-tests-4ia8</link>
      <guid>https://forem.com/rweisleder/refactoring-legacy-code-can-we-trust-existing-tests-4ia8</guid>
      <description>&lt;p&gt;Recently, I saw an interesting question on LinkedIn: "When making a moderately large refactor, should we trust the tests we already have, or should we drive our refactor with new tests?"&lt;/p&gt;

&lt;p&gt;As an independent consultant who is bringing legacy systems into the future, of course this question is of great interest to me. First of all, in legacy code, tests do not always exist or the code coverage is not that high. My first step is always to verify the existence of tests and evaluate their coverage. It's important to ensure that all critical areas, especially those that will be refactored, are well covered by tests. If not, then adding or improving tests is essential.&lt;/p&gt;

&lt;p&gt;Understanding the tests is as important as having them. If they don't accurately reflect the business requirements, I will then focus on refining them or creating new tests. This approach not only helps to understand the codebase, but also to build confidence in its reliability. In essence, getting to know the code through testing is important to me.&lt;/p&gt;

&lt;p&gt;When it comes to the refactoring itself, the goal is to change the structure without changing the business logic. This is where the IDE and automated refactoring tools are invaluable. They're less likely to make mistakes than moving code around by hand.&lt;/p&gt;

&lt;p&gt;So, to answer the original question: First, we need to have enough tests we can trust. Trust can be gained by having sufficient knowledge about the code unit to be refactored. This can be done, for example, by writing new tests. Automated tools help us to make the refactoring itself less error-prone.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on LinkedIn. &lt;a href="https://www.linkedin.com/in/roland-weisleder"&gt;Follow me&lt;/a&gt; there for more tips on working with legacy systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>refactoring</category>
      <category>legacy</category>
      <category>programming</category>
    </item>
    <item>
      <title>Have You Seen Your Tests Fail?</title>
      <dc:creator>Roland Weisleder</dc:creator>
      <pubDate>Thu, 05 Oct 2023 06:01:49 +0000</pubDate>
      <link>https://forem.com/rweisleder/have-you-seen-your-tests-fail-3n7k</link>
      <guid>https://forem.com/rweisleder/have-you-seen-your-tests-fail-3n7k</guid>
      <description>&lt;p&gt;You might think this is a rhetorical question, since Test-Driven Development (TDD) is promoted everywhere. According to TDD, we first write a failing test for a new requirement. Then, in a second step, we write just enough code to make the test pass. Finally, we clean up the code and have the tests as a guarantee that nothing breaks. And then the cycle starts all over again.&lt;/p&gt;

&lt;p&gt;But this test-first approach is not used by everyone. And it's even less likely to be used consistently all the time.&lt;br&gt;
A second point is that "writing just enough code" is sometimes harder than expected. At least for me, it often happens that I already have a rough idea of what the code will look like in the end. Without realizing it, I write more code than I actually need for the current test.&lt;/p&gt;

&lt;p&gt;But how can we verify that our tests fail when a functionality breaks? How to test our tests?&lt;/p&gt;

&lt;p&gt;One approach is Mutation Testing. In this approach, bugs are deliberately introduced into the production code. For example, conditions are inverted or entire statements are removed. The goal is to find out if the tests fail and thus find the built-in bug.&lt;/p&gt;

&lt;p&gt;For Mutation Testing, there are libraries that automate the process. But the execution can be very time-consuming. Sometimes manual Mutation Testing is sufficient by modifying the newly written code and seeing if the newly written tests fail.&lt;br&gt;
To test my tests, I usually do exactly this: Just change the code and deliberately introduce errors. If the tests then fail with a helpful error message, even better. That gives me more confidence in my tests.&lt;/p&gt;

&lt;p&gt;If the created mutations, automated or manual, are not detected, there may be room to improve the tests, or we may have more code than necessary. However, we should also make sure that production code and test code are not too tightly coupled. Then we run the risk of tests unnecessarily getting in the way of major changes or refactorings.&lt;/p&gt;

&lt;p&gt;Therefore: Try to break your code and Happy Testing!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Flag Parameter Anti-Pattern</title>
      <dc:creator>Roland Weisleder</dc:creator>
      <pubDate>Thu, 03 Nov 2022 12:18:04 +0000</pubDate>
      <link>https://forem.com/rweisleder/the-flag-parameter-anti-pattern-1j82</link>
      <guid>https://forem.com/rweisleder/the-flag-parameter-anti-pattern-1j82</guid>
      <description>&lt;p&gt;While implementing a new feature, I came across the &lt;em&gt;flag parameter&lt;/em&gt; anti-pattern in two unrelated places. I would like to take this as an opportunity to take a closer look at this anti-pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple example
&lt;/h2&gt;

&lt;p&gt;Lets assume we want to load all PDF documents via an API method. This could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DocumentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadDocuments&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  It Starts Smelling
&lt;/h2&gt;

&lt;p&gt;In the next step we need a method to load all TIFF documents. Since the difference in implementation might be only one line of code, the result might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DocumentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * @param loadTiff true: loads TIFF documents - false: loads PDF documents
     */&lt;/span&gt;
    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadDocuments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;loadTiff&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation is also modified very quickly with an additional if block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadDocuments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;loadTiff&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// load PDF documents by default&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loadTiff&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// except when TIFFs are requested&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if we look at the client side of this API, we already notice an unpleasant smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;documentService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadDocuments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this code point, can you tell what the meaning of &lt;code&gt;false&lt;/code&gt; is without looking at the definition of the method? And what happens if we change this to &lt;code&gt;true&lt;/code&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Smell Begins to Stink
&lt;/h2&gt;

&lt;p&gt;In the next step we also need a method to load RTF documents. Again, the difference in implementation is only one line of code. But how can we reuse the existing method without having to re-implement the logic? The flag parameter stands in our way! The &lt;code&gt;boolean&lt;/code&gt; parameter can only take two states, &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. (Okay, the clever Java developer changes this to a &lt;code&gt;Boolean&lt;/code&gt; parameter and has &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;null&lt;/code&gt; as choices).&lt;/p&gt;

&lt;p&gt;However, the flag parameter also shows us something else: the single responsibility principle is violated here. In fact, this method currently has more than one responsibility. On the one hand, it knows how to load PDF documents. On the other hand, it also knows how to load TIFF documents. Or more generally: such a method does two different things - once on &lt;code&gt;true&lt;/code&gt; and once on &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possible Solutions
&lt;/h2&gt;

&lt;p&gt;Spontaneously I can think of two simple ways to get rid of the flag parameter.&lt;/p&gt;

&lt;p&gt;Option 1: We define an interface for the document types to query for information. Then we can generalize the method by using the document type as a parameter. However, there is a possibility of unnecessary &lt;a href="https://wiki.c2.com/?OverGeneralizationOfBusinessLogic"&gt;over-generalization of the business logic&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DocumentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadDocuments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentType&lt;/span&gt; &lt;span class="n"&gt;documentType&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Option 2: We create a specific method for each possible domain context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DocumentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadPdfDocuments&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadTiffDocuments&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadRtfDocuments&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both cases, from the client's side, this results in readable code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;documentService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadDocuments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PDF&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;documentService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadPdfDocuments&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What About Setter Methods?
&lt;/h2&gt;

&lt;p&gt;If we were strict, then we would also have to change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setEnabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;enable&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;disable&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;However, we don't have to be more papal than the pope here. If I had to choose between&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setEnabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actionCheckBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isChecked&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actionCheckBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isChecked&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enable&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for the client code, I would stay with the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://martinfowler.com/bliki/FlagArgument.html"&gt;FlagArgument&lt;/a&gt; by Martin Fowler&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.informit.com/articles/article.aspx?p=1392524"&gt;Clean Code Tip: Eliminate Boolean Arguments&lt;/a&gt; by Uncle Bob&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I hope this article was helpful to you. Feel free to leave a comment. For more Java stuff, follow me on &lt;a href="https://twitter.com/Ro_Wei"&gt;Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>patterns</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Unit Tests Will Save You a Lot of Time</title>
      <dc:creator>Roland Weisleder</dc:creator>
      <pubDate>Thu, 06 Oct 2022 11:20:43 +0000</pubDate>
      <link>https://forem.com/rweisleder/why-unit-tests-will-save-you-a-lot-of-time-3ngf</link>
      <guid>https://forem.com/rweisleder/why-unit-tests-will-save-you-a-lot-of-time-3ngf</guid>
      <description>&lt;p&gt;When you as a developer hear that you should write unit tests, it sounds like more effort at first. The code you have written works, as you have already seen by trying it.&lt;/p&gt;

&lt;p&gt;However, the world around it is constantly changing. And how can you be sure that the code still works despite changes from the outside?&lt;/p&gt;

&lt;h2&gt;
  
  
  Date Format?
&lt;/h2&gt;

&lt;p&gt;Let's assume that in our program there is a function to parse strings as dates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @param input a date with format "dd.MM.yy HH:mm"
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="nf"&gt;parseDate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;ParseException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DateFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use a class from the JDK here and even describe in the Javadoc which format the &lt;code&gt;input&lt;/code&gt; parameter should have. Once we have tried this, what else can go wrong? Surely this will work forever.&lt;/p&gt;

&lt;p&gt;Even after updating from Java 8 to Java 11, everyone would assume that the function still works as described, right? After all, we are only using a class from the JDK.&lt;/p&gt;

&lt;p&gt;Let's do a test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;parseDate_should_parse_String_to_Date&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;ParseException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parseDate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"14.02.09 00:31"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hasYear&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2009&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hasMonth&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hasDayOfMonth&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hasHourOfDay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hasMinute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Java 8, the test is successful. Everyone would probably expect the same with Java 11. However, the result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java.text.ParseException: Unparseable date: "14.02.09 00:31"

    at java.base/java.text.DateFormat.parse(DateFormat.java:395)
    at org.example.Dummy.parseDate(Dummy.java:31)
    at org.example.DummyTest.parseDate_should_parse_String_to_Date(DummyTest.java:36)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Java 11 the default pattern of DateFormat was changed from "dd.MM.yy HH:mm" to "dd.MM.yy, HH:mm". Now as a developer you have to make a choice: Adapt the implementation of parseDate so that the interface (see Javadoc) is fulfilled again? Or adapt the interface (Javadoc) and all callers to the new behavior?&lt;/p&gt;

&lt;h2&gt;
  
  
  Currency Format?!?
&lt;/h2&gt;

&lt;p&gt;A second example inspired by the update from Java 8 to Java 11. Let's assume that in our program there is a function to format numbers as currency. For simplicity, let's again take a class from the JDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Formats 13.37 as "13,37 €"
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;formatCurrency&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrencyInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GERMANY&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's do a test for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;formatCurrency_should_format_double_to_String&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;formatted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formatCurrency&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;13.37&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatted&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"13,37 €"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Java 8 the test is successful. However, with Java 11 you get the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Expecting:
 &amp;lt;"13,37 €"&amp;gt;
to be equal to:
 &amp;lt;"13,37 €"&amp;gt;
but was not.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, solution: With Java 8 a normal space (ASCII code 0x20) was put between number and currency symbol. With Java 11, a non-breaking space (ASCII code 0xA0) is used. They both look the same, but they are not the same.&lt;/p&gt;

&lt;p&gt;This change in the JDK then has the effect that &lt;code&gt;formatCurrency(13.37).replace(" €", "")&lt;/code&gt; still returns the string &lt;code&gt;"13.37 €"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These specific cases were deeply hidden in the system. After a Java update, no one would have noticed these changes, neither in a local test, nor in a customers' test system. This would be a typical candidate for "bugs that first become visible in the production system". Fortunately, in both cases there were unit tests for the affected parts.&lt;/p&gt;

&lt;p&gt;Unit tests are always a good way to ensure that a function works as expected by the developer. Without unit tests you will only notice very late or too late when something does not work as expected.&lt;/p&gt;

&lt;p&gt;By the way, if you try out the code you wrote, you could convert this "trying out" directly into tests, couldn't you? Then the testing is also much faster, even if other developers want to try something.&lt;/p&gt;

</description>
      <category>java</category>
      <category>testing</category>
      <category>junit</category>
      <category>tdd</category>
    </item>
  </channel>
</rss>
