<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>The Code Whisperer</title>
    <description></description>
    <link>https://blog.thecodewhisperer.com/</link>
    <atom:link href="https://blog.thecodewhisperer.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 04 Apr 2026 01:02:07 -0300</pubDate>
    <lastBuildDate>Sat, 04 Apr 2026 01:02:07 -0300</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>
    
      <item>
        <title>A Tale of map and parseInt in Three Acts, or WAT You Will</title>
        <description>&lt;h1 id=&quot;a-tale-of-map-and-parseint-in-three-acts&quot;&gt;A Tale of map and parseInt in Three Acts&lt;/h1&gt;
&lt;h2 id=&quot;act-1-what&quot;&gt;Act 1: What?!&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { describe, it, expect } from &amp;#39;@jest/globals&amp;#39;;

describe(&amp;quot;map parseInt over an array of strings&amp;quot;, () =&amp;gt; {
  it(&amp;quot;should parse both numbers, but doesn&amp;#39;t seem to&amp;quot;, () =&amp;gt; {
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(parseInt)).toStrictEqual([0, 0]);
  });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The actual result is &lt;code&gt;[0, NaN]&lt;/code&gt;. Huh.&lt;/p&gt;
&lt;h2 id=&quot;act-2-hmmm.&quot;&gt;Act 2: Hmmm….&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { describe, it, expect } from &amp;#39;@jest/globals&amp;#39;;

describe(&amp;quot;map parseInt over an array of strings&amp;quot;, () =&amp;gt; {
  it(&amp;quot;should parse both numbers, but doesn&amp;#39;t seem to&amp;quot;, () =&amp;gt; {
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(s =&amp;gt; parseInt(s))).toStrictEqual([0, 0]);
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(parseInt)).toStrictEqual([0, NaN]);
  });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This test passes. Wait… when does eta-conversion fail?!&lt;/p&gt;
&lt;p&gt;When there is more than one argument to the function we are “mapping”! What does &lt;code&gt;Array.map()&lt;/code&gt; actually do?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;callback&lt;/em&gt; is called with three arguments: the value of the element, the index of the element, and the object being traversed.&lt;/p&gt;
&lt;p&gt;— &lt;a href=&quot;https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.map&quot; class=&quot;uri&quot;&gt;https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.map&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;act-3-aha&quot;&gt;Act 3: Aha!&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { describe, it, expect } from &amp;#39;@jest/globals&amp;#39;;

describe(&amp;quot;map parseInt over an array of strings&amp;quot;, () =&amp;gt; {
  it(&amp;quot;should parse both numbers, but doesn&amp;#39;t seem to&amp;quot;, () =&amp;gt; {
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(s =&amp;gt; parseInt(s))).toStrictEqual([0, 0]);
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(parseInt)).toStrictEqual([0, NaN]);
    expect(parseInt(&amp;quot;0&amp;quot;, 0, [&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;])).toStrictEqual(0);
    expect(parseInt(&amp;quot;0&amp;quot;, 1, [&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;])).toStrictEqual(NaN);    // because radix != 0 and radix &amp;lt; 2
  });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;parseInt()&lt;/code&gt; interprets the index as a radix, and the radix is not 0 (where it would default to 10) and not 2 (which would result in interpreting the text as a binary number), the result is &lt;code&gt;NaN&lt;/code&gt;. Obviously. (&lt;a href=&quot;https://tc39.es/ecma262/multipage/global-object.html#sec-parseint-string-radix&quot;&gt;Read step 8.&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;And that’s how we learn that eta-conversion with &lt;code&gt;Array.map()&lt;/code&gt; in TypeScript is &lt;em&gt;special&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { describe, it, expect } from &amp;#39;@jest/globals&amp;#39;;

describe(&amp;quot;map parseInt over an array of strings&amp;quot;, () =&amp;gt; {
  it(&amp;quot;should parse both numbers, but doesn&amp;#39;t seem to&amp;quot;, () =&amp;gt; {
    // Explicit parameter passing works as expected
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(s =&amp;gt; parseInt(s))).toStrictEqual([0, 0]);

    // eta-conversion fails, because map() passes 3 arguments to the function, not only 1
    expect([&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].map(parseInt)).toStrictEqual([0, NaN]);

    // Notably, map() invokes callback(element, index, sourceObject),
    // but JavaScript/TypeScript can ignore superfluous arguments, which means...
    expect(parseInt(&amp;quot;0&amp;quot;, 0, [&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;])).toStrictEqual(0);
    expect(parseInt(&amp;quot;0&amp;quot;, 1, [&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;])).toStrictEqual(NaN);    // because radix != 0 and radix &amp;lt; 2
  });
});&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Thu, 19 Mar 2026 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-tale-of-map-and-parseInt-in-three-acts</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-tale-of-map-and-parseInt-in-three-acts</guid>
        
        
        <category>Microtechniques</category>
        
      </item>
    
      <item>
        <title>Clarifying the Rule of Three in Refactoring</title>
        <description>&lt;p&gt;Do you know the Rule of Three in refactoring? (If not, then read the References section.) More than a quarter century after this heuristic received its name, it continues to confuse and divide programmers. Most notably, some programmers swear by it while others (and I count myself as one) take a more relaxed attitude towards it. This lies at the center of the ongoing debate between whether to favor removing duplication or to wait before extracting an abstraction, lest it become unhelpful.&lt;/p&gt;
&lt;p&gt;So what’s up with that?&lt;/p&gt;
&lt;p&gt;I think of the Rule of Three as a way to stop Advanced Beginners&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; from greedily removing all duplication without considering for a moment whether that duplication is &lt;a href=&quot;https://en.wikipedia.org/wiki/No_Silver_Bullet&quot;&gt;accidental or essential&lt;/a&gt;. We could argue about the need for mitigating this particular risk, but the rule seems to try to balance learning and performance. When the programmer is &lt;strong&gt;primarily learning about how to design by refactoring, rather than making choices up front&lt;/strong&gt;, they might remove all duplication greedily in order to use regret as a tool for sharpening their judgment; when the programmer is &lt;strong&gt;primarily performing refactoring as a technique for guiding designs to evolve&lt;/strong&gt;, they might delay removing duplication in order to avoid rework when later they reintroduce duplication that they regretted removing. With not too much effort, you could likely find many articles whose recommendations optimize for the &lt;em&gt;performing&lt;/em&gt; case, but if the programmer routinely denies themself the chance to go overboard, then how will they learn?&lt;/p&gt;
&lt;p&gt;Even beyond this question, I don’t mind removing duplication more aggressively, primarily because &lt;strong&gt;I don’t mind inlining when I regret my choice&lt;/strong&gt;. I genuinely don’t know what stops other practitioners from making peace with undoing some of their refactorings once they experience significant regret. I seem to recall, in the early days of learning this stuff, plenty of advice about mentally preparing to do a lot of concern-inducing extracting, inlining, extracting, inlining, extracting, inlining as part of the learning process. And not to panic, but to let the learning happen. How else could it be?&lt;/p&gt;
&lt;h1 id=&quot;what-now&quot;&gt;What Now?!&lt;/h1&gt;
&lt;p&gt;Should you follow the Rule of Three? &lt;strong&gt;I don’t know&lt;/strong&gt;. Instead, I feel pretty confident about these statements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Removing duplication aggressively, even “too aggressively”, plays a role in developing design judgment.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Removing duplication leads to finding new, helpful abstractions&lt;/a&gt; that might have been hiding in the design.&lt;/li&gt;
&lt;li&gt;If you feel more comfortable inlining, then you don’t have to worry so much about whether you’ll regret extracting (and in particular, removing duplication).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you prefer strongly (always?) to wait until you see three copies before removing duplication, then I encourage you to prefer this for reasons more helpful than some vague fear of “doing it wrong”.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Wikipedia, &lt;a href=&quot;https://en.wikipedia.org/wiki/Rule_of_three_(computer_programming)&quot;&gt;“Rule of three (computer programming)”&lt;/a&gt;. A brief introduction, then pointers to similar concepts.&lt;/p&gt;
&lt;p&gt;Wikipedia, &lt;a href=&quot;https://en.wikipedia.org/wiki/No_Silver_Bullet&quot;&gt;“No Silver Bullet”&lt;/a&gt;. About Fred Brooks’s essay in which he prominently uses the terms “essential” and “accidental” to distinguish two kinds of cost in software design.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;“Putting an Age-Old Battle to Rest”&lt;/a&gt;. An overview of the Simple Design Dynamo, which describes how removing duplication and improving names form a virtuous cycle that you could use to guide the evolution of your software designs with confidence.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://www.youtube.com/watch?v=WSes_PexXcA&quot;&gt;“7 minutes, 26 seconds, and the Fundamental Theorem of Agile Software Development”&lt;/a&gt;. A lightning talk centered on the importance of refactoring in addressing the risks inherent in forecasting the cost of software projects. Some light beat poetry.&lt;/p&gt;
&lt;p&gt;Martin Fowler, &lt;a href=&quot;https://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Signature/dp/0134757599?tag=jbrains.ca-20&quot;&gt;&lt;em&gt;Refactoring: Improving the Design of Existing Code&lt;/em&gt;&lt;/a&gt;. The classic text on refactoring, in which Fowler describes the Rule of Three.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;This term refers to the Dreyfus Model of Skill Acquisition. An Advanced Beginner is just beginning to feel comfortable following a new set of steps and is starting to form value judgments about what they are doing.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Fri, 07 Nov 2025 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/clarifying-the-rule-of-three-in-refactoring</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/clarifying-the-rule-of-three-in-refactoring</guid>
        
        
        <category>Simple Design</category>
        
        <category>Evolutionary Design</category>
        
        <category>Microtechniques</category>
        
        <category>Refactoring</category>
        
        <category>Removing Duplication Deftly</category>
        
      </item>
    
      <item>
        <title>Going Further with One Outcome Per Test</title>
        <description>&lt;p&gt;Today I read Jason Gorman’s &lt;a href=&quot;https://codemanship.wordpress.com/2025/10/13/tdd-under-the-microscope-3-one-outcome-per-test/&quot;&gt;“TDD Under the Microscope: One Outcome Per Test”&lt;/a&gt;. I like this &lt;em&gt;and&lt;/em&gt; I propose one step more: the emergence of two interesting outcomes itself signals a potentially-helpful abstraction.&lt;/p&gt;
&lt;p&gt;First, let me restate the principle in Jason’s article, which I tend to follow:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When one action leads to two interesting outcomes, consider writing two tests with the same action.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;… but it gets even better when I go further.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When one action leads to two interesting outcomes, I consider those two outcomes as two listeners to the some (new, emerging) domain event, particularly when those two interesting outcomes seem independent of each other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;jasons-example&quot;&gt;Jason’s Example&lt;/h1&gt;
&lt;p&gt;To return to Jason’s example, the action is “buy item X with payment card Y”. The two interesting outcomes, which he writes as assertions, are “check the inventory of X” and “verify the attempt to charge payment card Y”. It seems to me that these are independent outcomes… although perhaps not. (I’ll come back to this later in this article.) I try to model them as either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;two implementations of the same interface, or&lt;/li&gt;
&lt;li&gt;two listeners to the same domain event&lt;/li&gt;
&lt;/ul&gt;
&lt;aside&gt;
I consider these two conceptions equivalent, but I digress. (More on that later, if you’d like. Please let me know!)
&lt;/aside&gt;
&lt;h2 id=&quot;finding-the-abstraction-or-domain-event&quot;&gt;Finding the Abstraction or Domain Event&lt;/h2&gt;
&lt;p&gt;What’s the abstraction? What’s the domain event? Well… &lt;strong&gt;what is the Good Business Reason to charge payment card Y and change the inventory of item X?&lt;/strong&gt; It seems that we have sold an item to a customer—or at least have been asked to sell an item to a customer. So the domain event could be “sold item X to customer Y”. And, for now at least, it might be good enough for our purposes to let the payment card stand in for the customer. (That’s the Memento pattern!)&lt;/p&gt;
&lt;p&gt;But that might seem weird: “buy item X with payment card Y” seems to result in “Yes, item X was bought with payment card Y”. That doesn’t seem very helpful as a test, because it seems tautological. But the principle is sound, so how &lt;em&gt;could&lt;/em&gt; this be helpful? Maybe we can improve the design a slightly different way.&lt;/p&gt;
&lt;h1 id=&quot;lets-do-some-really-fast-tdd-in-our-heads&quot;&gt;Let’s Do Some Really Fast TDD In Our Heads&lt;/h1&gt;
&lt;p&gt;Well… what could possibly stop us from allowing item X to be bought with payment card Y?&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; I often use the answers to this question to add items to my test list. And in the process, I suddenly realize that what we truly have is closer to this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Charging payment card Y might fail, and if it does, then the purchase must fail. (I assume so. It seems sensible.)&lt;/li&gt;
&lt;li&gt;Updating the inventory of item X might fail, but if it does, that’s a bookkeeping issue we can fix later, so the purchase does not need to fail. Maybe we log a future task to check the inventory. Maybe this becomes a new feature somewhere….&lt;/li&gt;
&lt;li&gt;The inventory of item X might be lower than the number needed to fulfil the purchase, and if it is, then the purchase must fail. (Or must it? Keep reading.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It might make sense to check inventory first, then try to charge the payment card, but &lt;strong&gt;it might be better for business&lt;/strong&gt; to charge the payment card first, then check the inventory. (Someone will have to decide this.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Even if we don’t extract an abstraction nor introduce a domain event, merely &lt;em&gt;thinking about it&lt;/em&gt; helps us identify some complications worth understanding before we commit too much to building the feature.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What this tells me is that &lt;strong&gt;there are two different candidate domain events&lt;/strong&gt;: “purchase attempted” and “purchase approved”. Charging the card and checking the inventory both listen to “purchase attempted”, whereas update the inventory listens to “purchased approved”. And charging the card fires “purchase approved” when it completes successfully. It seems that “assert inventory is reduced to 6” makes more sense in the “purchase approved” tests than in the “purchase attempted” tests.&lt;/p&gt;
&lt;aside&gt;
Even when I refer to code as a listener to a domain event, if it turns out that there is only one, mandatory, perpetual listener to a domain event, then that’s simply the implementation of a method. Sending a message to an object is structurally equivalent to firing a synchronous event to a known, mandatory listener. I find it more flexible to talk broadly about listeners to domain events, then figure out later whether to implement it as a simple method.
&lt;/aside&gt;
&lt;p&gt;Jason’s original test seems to me like a test for “attempt purchase”, which (in my new conception of the design) would result in either “purchase approved” or “purchase rejected”. And then from there, if the purchase were approved, then and only then would we need to update the inventory for the purchased item. &lt;strong&gt;What seemed like they might be independent listeners to the same domain event end up actually being outcomes of two different actions!&lt;/strong&gt; This happens quite often to me when I try to identify the domain events in even the simplest-looking workflows!&lt;/p&gt;
&lt;p&gt;But wait… I have 25 years of experience practising Evolutionary Design and TDD. Maybe that’s the only reason I can see all this. Maybe you worry you won’t see this. I don’t think that’s true; I think you can see it. At a minimum, I feel confident that you could build the habits to see it.&lt;/p&gt;
&lt;h1 id=&quot;the-long-way-remains-safe&quot;&gt;The Long Way Remains Safe&lt;/h1&gt;
&lt;p&gt;I desperately want to emphasize now that I would have discovered all this if I’d gone “the long way”. It is enough to start with Jason’s tests and follow the &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Simple Design Dynamo&lt;/a&gt;. I would have noticed duplication in the tests, I would have wondered how to remove it, and then I would probably have experimented with doing it. In particular, I’d have noticed some (very slightly) complicated logic, such as cases for:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;inventory enough and card payment succeeds&lt;/li&gt;
&lt;li&gt;inventory enough and card payment fails&lt;/li&gt;
&lt;li&gt;inventory not enough and card payment succeeds&lt;/li&gt;
&lt;li&gt;inventory not enough and card payment fails&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This would have led me to ask the question, &quot;Wait, if card payment fails, then who cares about the inventory? And if the inventory isn’t enough, then who cares about the card payment? Oh! But wait, wait! Wouldn’t it be better for business to charge the card anyway, then figure out later whether we can source the product even when inventory is low?! I mean, the inventory system isn’t perfect, and we’d hate to lose a sale because the inventory system incorrectly thinks we don’t have enough stock on hand to fulfil the purchase…&lt;/p&gt;
&lt;p&gt;“Aha! There’s no point in updating the inventory until we know the payment succeeds, so there’s some kind of intermediate result there. It would be easier to test ‘update inventory’ by letting that be the outcome from a &lt;em&gt;successful&lt;/em&gt; purchase and not merely an &lt;em&gt;attempted&lt;/em&gt; purchase.”&lt;/p&gt;
&lt;p&gt;The key point here is that even if I didn’t quickly see all this in my head, I would have seen it when I started trying to make tests pass, then I would have been able to refactor in that direction. The more I practised, the easier this felt and the quicker I went, until eventually I began to see the shortcuts sooner by doing TDD in my head.&lt;/p&gt;
&lt;h1 id=&quot;a-conclusion&quot;&gt;A Conclusion&lt;/h1&gt;
&lt;p&gt;Here are some related principles I use in software design:&lt;/p&gt;
&lt;h2 id=&quot;one-action-per-test&quot;&gt;One Action Per Test&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Insist&lt;/strong&gt; on only one action per test. If you discover the structure “action, then assertions, then action, then assertions”, then &lt;em&gt;almost always&lt;/em&gt; split this into separate tests for each action.&lt;/p&gt;
&lt;p&gt;If you do this, then you’ll probably discover that it helps to identify the state of the system just before the second action, rather than needing to execute the first action to reach that state.&lt;/p&gt;
&lt;h2 id=&quot;one-outcome-per-test&quot;&gt;One Outcome Per Test&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Always be open to experimenting&lt;/strong&gt; with one outcome per test. If you want to check multiple outcomes in the same test, then assume that the workflow that generates multiple outcomes is “too complicated” and look for interesting intermediate results or emerging domain events.&lt;/p&gt;
&lt;p&gt;If you do this, then you’ll probably simplify the tests at the same time as you better understand the tedious details of the workflow, especially error conditions and mutually-exclusive states. If this helps you avoid allowing your system to reach what should be an impossible state, then you’ve made life much easier for future you!&lt;/p&gt;
&lt;h2 id=&quot;one-assertion-per-test&quot;&gt;One Assertion Per Test&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Try hard to write&lt;/strong&gt; only one assertion per test. (This is not &lt;em&gt;quite&lt;/em&gt; the same as “one outcome per test”.) If you need more than one assertion to describe a single logical outcome, then consider packaging all the outcomes into a single bundle (&lt;code&gt;struct&lt;/code&gt;, object, dictionary).&lt;/p&gt;
&lt;p&gt;If you do this, then you might discover helpful missing elements in your design. This happens to me especially when I struggle to name some bundle of things that evidently belong together, then finally find a sensible name. I don’t remember the last time I regretted doing this.&lt;/p&gt;
&lt;h2 id=&quot;multiple-truly-independent-outcomes-are-listeners-to-a-new-domain-event&quot;&gt;Multiple Truly-Independent Outcomes are Listeners to a New Domain Event&lt;/h2&gt;
&lt;p&gt;If you have more than one &lt;em&gt;truly&lt;/em&gt;-independent outcome to a single action in a test (or group of tests), then &lt;strong&gt;consider them as independent listeners to a domain event&lt;/strong&gt;. Maybe even design them using the Publish/Subscribe or Observer/Observable pattern.&lt;/p&gt;
&lt;p&gt;Trying to make them truly independent avoids potential defects and simplifies tests, because most programming languages force you to choose the sequence of statements, even when they are truly independent of each other. It can both be simpler and build more confidence to check each outcome in isolate from the other, both because you avoid variations in the combinations of states that don’t matter or should be impossible &lt;em&gt;and&lt;/em&gt; because you open up the possibility for making behavior asynchronous with almost complete confidence that doing so will create no additional risk worth checking with a complicated automated test.&lt;/p&gt;
&lt;p&gt;At the very least, trying to do this helps you identify the parts of the workflow that truly need to be arranged in a sequence and the parts that can be treated entirely independently and perhaps run in parallel. The resulting design becomes typically simpler to test, requiring fewer tests that run smaller parts of the system in more isolation. It also becomes easier and safer to add parallelization. Simpler, faster, clearer.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;This is an example of &lt;em&gt;Chet Hendrickson Technique&lt;/em&gt;, which I use as part of Value-Driven Product Development to explore either a feature, a feature area, or even an entire nebulous product idea in detail. I’m told it’s related to “context diagramming”.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 19 Oct 2025 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/going-further-with-one-outcome-per-test</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/going-further-with-one-outcome-per-test</guid>
        
        
        <category>Simple Design</category>
        
        <category>Evolutionary Design</category>
        
        <category>Microtechniques</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>Saff Squeeze: Example 1</title>
        <description>&lt;h1 id=&quot;before-you-begin&quot;&gt;Before You Begin&lt;/h1&gt;
&lt;p&gt;What is the Saff Squeeze? &lt;a href=&quot;/permalink/the-saff-squeeze&quot;&gt;Read this tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;the-example&quot;&gt;The Example&lt;/h1&gt;
&lt;p&gt;I use &lt;code&gt;jq&lt;/code&gt; to turn JSON into Plain Text Accounting journal entries. In particular, I administer a bowling league and use &lt;code&gt;hledger&lt;/code&gt; to track the league finances. Each week, we collect cash from bowlers, pay some of that money to bowling center, and use the rest to fund prizes.&lt;/p&gt;
&lt;p&gt;When we collect cash, we record what we collect, because I value accuracy. Here is a JSON document that represents the paper document we fill in each week.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &amp;quot;date&amp;quot;: &amp;quot;2023-11-22&amp;quot;,
  &amp;quot;prepaid_bowling_fees&amp;quot;: [],
  &amp;quot;tournament&amp;quot;: &amp;quot;2023-2024:Singles Sprint&amp;quot;,
  &amp;quot;strike_pot_ticket_sales_in_cents&amp;quot;: 6500,
  &amp;quot;money_slips&amp;quot;: {
    &amp;quot;bowlers&amp;quot;: {
      &amp;quot;regulars&amp;quot;: { &amp;quot;fulls&amp;quot;: 19, &amp;quot;spares&amp;quot;: 0 },
      &amp;quot;youths&amp;quot;: { &amp;quot;fulls&amp;quot;: 5, &amp;quot;spares&amp;quot;: 1 }
    },
    &amp;quot;extra_prize_funds&amp;quot;: 2
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have this particular example handy because processing this document creates a small problem.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2023-11-22  Strike Pot ticket sales
    Revenues:Strike Pot Ticket Sales    -65 CAD
    Assets:Cash:Strike Pot Fund    32.5 CAD
    Assets:Cash:General Prize Fund:Reserved For Tournament:2023-2024:Singles Sprint    32.5 CAD

2023-11-22  Bowling Fees collected
    Revenues:Bowling Fees    -289.75 CAD    ; 19 regulars, 5 youths, 0 regular spares, 1 youth spares
    Liabilities:Lineage Payable    194.7 CAD    ; 19 regular bowlers
    Liabilities:Lineage Payable    49.45 CAD    ; 6 youth bowlers
    Assets:Cash:General Prize Fund:Reserved For Tournament:2023-2024:Singles Sprint

2023-11-22  Lineage paid
    Expenses:Lineage    244.14999999999998 CAD
    Liabilities:Lineage Payable&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Well, maybe not a &lt;em&gt;problem&lt;/em&gt;, but a risk. I would feel much better if that “Lineage” expense amount were &lt;code&gt;244.15 CAD&lt;/code&gt;.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;
How big is this risk? Meh. I’m not interested in arguing about it here.
&lt;/p&gt;
&lt;p&gt;
It’s almost certainly not worth the investment in fixing the defect, let alone writing an article about it. It might not even be worth the investment of changing the amount by hand in the generated journal file. Even so, it’s the kind of risk that, when it becomes a problem, leads to hours and hours and hours of confusion under stress. For that reason, if I think I can fix it &lt;em&gt;easily&lt;/em&gt;, then I try to fix it. If I can’t fix it within about an hour, I move on and wait until I have more energy (and a better idea) to try again.
&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;So… why does this happen? Well, we can guess and look and guess and try and guess and poke around… or we can use the Saff Squeeze.&lt;/p&gt;
&lt;p&gt;But wait! how does one write automated tests for &lt;code&gt;jq&lt;/code&gt; code?&lt;/p&gt;
&lt;p&gt;I’ve never tried. Meh. I’m not going to bother. I can use the Saff Squeeze even without automated tests.&lt;/p&gt;
&lt;h1 id=&quot;its-like-the-saff-squeeze&quot;&gt;It’s &lt;em&gt;Like&lt;/em&gt; the Saff Squeeze…&lt;/h1&gt;
&lt;p&gt;Yes, the Saff Squeeze works really well when we have automated tests, then successively inline a part of the test, pruning away the irrelevant parts and adding assertions whenever the code tests an &lt;code&gt;if&lt;/code&gt; condition. We can still use it when we don’t have automated tests. That’s what I did, rather than invest time in figuring out how to write automated tests for &lt;code&gt;jq&lt;/code&gt;. (I’m sure someone has done that, but I’m not interested right now. I have an article to write!)&lt;/p&gt;
&lt;p&gt;I chose to write a &lt;code&gt;jq&lt;/code&gt; expression in a script, then successively inline parts of the expression until the defect became obvious. It’s not exactly the Saff Squeeze, but it’s &lt;em&gt;like&lt;/em&gt; the Saff Squeeze. And it captures the &lt;em&gt;intent&lt;/em&gt; of the Saff Squeeze.&lt;/p&gt;
&lt;h2 id=&quot;step-1-write-a-failing-test-that-demonstrates-the-defect&quot;&gt;Step 1: Write a Failing Test That Demonstrates the Defect&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Expenses:Lineage&lt;/code&gt; amount shows the problem, so I focus on the code that computes that value and discard the rest.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::lineage_paid_of&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that this line of code is similar to a unit test:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It provides the example input directly, using &lt;code&gt;jq -n&lt;/code&gt;, rather than insisting on providing the input data from a file, the way production code does.&lt;/li&gt;
&lt;li&gt;The example data includes only the parts of the input that the action of the test needs.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It invokes &lt;code&gt;lineage_paid_of&lt;/code&gt; directly, rather than running the code from end to end.&lt;/li&gt;
&lt;/ul&gt;
&lt;aside&gt;
&lt;p&gt;
Yes, I know: you don’t know the production code, so you can’t verify the claims I’m making about the production code. Trust me. I don’t have the energy to lie about it.
&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;When I run the test, I see an unrounded result, which I interpret as “test failed”.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;244.149999999998&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I would probably prefer to move this assertion to the script, but I don’t have the energy and this gives me enough information to move forward.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;
But wait! I don’t want to lose this information, because it’s exactly the kind of information that I’m likely to forget soon, then overpay to reverse-engineer in the future when I rediscover this script in two years. I can do better!
&lt;/p&gt;
&lt;p&gt;
I added an &lt;code&gt;echo&lt;/code&gt; message to this script that describes to the invoker how to interpret the results. It’s not quite as good as &lt;code&gt;assert_rounded()&lt;/code&gt;, but at least it doesn’t put the burden on whoever runs the script to figure out what is going on and why.
&lt;/p&gt;
&lt;p&gt;
When I need to do this more than once, I’ll figure out how to write &lt;code&gt;assert_rounded()&lt;/code&gt; in &lt;code&gt;jq&lt;/code&gt;. For now, &lt;strong&gt;it’s enough to have written things down&lt;/strong&gt;.
&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id=&quot;step-2-inline-the-action&quot;&gt;Step 2: Inline the Action&lt;/h2&gt;
&lt;p&gt;The Saff Squeeze has two key parts: inline the action where the defect probably lies and prune away irrelevant details. Doing this over and over eventually makes the defect easy to see merely by reading the test.&lt;/p&gt;
&lt;p&gt;I inlined the action and added that to the script.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def lineage_paid_of:
  regulars_lineage_payable_of + youths_lineage_payable_of;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::lineage_paid_of&amp;#39;
jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::regulars_lineage_payable_of + ProcessMoneySlips::youths_lineage_payable_of&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I expect this to show the same unrounded output twice and it does.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;244.149999999998
244.149999999998&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But now it’s already becoming difficult to understand what’s going on, so I add some labels to the calculations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo -n &amp;quot;lineage_paid_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::lineage_paid_of&amp;#39;
echo -n &amp;quot;inlined lineage_paid_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::regulars_lineage_payable_of + ProcessMoneySlips::youths_lineage_payable_of&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes the output easier to understand.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lineage_paid_of: 244.14999999999998
inlined lineage_paid_of: 244.14999999999998&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But remember that I already added some text to explain what we’re looking at here and how to interpret it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.

lineage_paid_of: 244.14999999999998
inlined lineage_paid_of: 244.14999999999998&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-3-prune-irrelevant-details&quot;&gt;Step 3: Prune Irrelevant Details&lt;/h2&gt;
&lt;p&gt;There are no ignored branches to prune away, so there’s nothing to do at this step.&lt;/p&gt;
&lt;h2 id=&quot;step-4-inline-more-of-the-action&quot;&gt;Step 4: Inline More of the Action&lt;/h2&gt;
&lt;p&gt;At this step, we could inline each part of the calculation and see what happens, but my intuition tells me that it might be helpful to split this into two tests: one for &lt;code&gt;regulars_lineage_payable_of&lt;/code&gt; and one for &lt;code&gt;youths_lineage_payable_of&lt;/code&gt;. I suppose you could think of this as pruning irrelevant details, and therefore part of the preceding step.&lt;/p&gt;
&lt;p&gt;I add these two lines to the script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo -n &amp;quot;regulars_lineage_payable_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::regulars_lineage_payable_of&amp;#39;
echo -n &amp;quot;youths_lineage_payable_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::youths_lineage_payable_of&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I could have pruned away the irrelevant parts of the input, but I chose not to out of the purest laziness and excitement. I’ll do that as part of cleaning up before moving on. (Future jbrains actually did this. Keep reading.)&lt;/p&gt;
&lt;p&gt;When I run the script, I expect to see more unrounded amounts, but then I’m surprised.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.

lineage_paid_of: 244.14999999999998
inlined lineage_paid_of: 244.14999999999998
regulars_lineage_payable_of: 194.7
youths_lineage_payable_of: 49.45&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Excellent! This immediately suggests that the problem lies in adding floating-point values, not in computing each of the two values to add together. This allows me to prune irrelevant details!&lt;/p&gt;
&lt;h2 id=&quot;step-5-prune-irrelevant-details&quot;&gt;Step 5: Prune Irrelevant Details&lt;/h2&gt;
&lt;p&gt;What happens if I just add those constants? Does that already demonstrate the problem?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo -n &amp;quot;add floating-point constants: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;194.7 + 49.45&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why yes, it does!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.

lineage_paid_of: 244.14999999999998
inlined lineage_paid_of: 244.14999999999998
regulars_lineage_payable_of: 194.7
youths_lineage_payable_of: 49.45
add floating-point constants: 244.14999999999998&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-6-eureka&quot;&gt;Step 6: Eureka!&lt;/h2&gt;
&lt;p&gt;I think I know the defect: it’s a limitation of floating-point arithmetic. This means that my code should add pennies as integers as long as possible, then convert to dollars only at the last possible moment. I confirm this guess with one more test.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo -n &amp;quot;add pennies, then convert to dollars: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;(19470 + 4945) / 100.0&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yup. Now I get &lt;code&gt;244.15&lt;/code&gt;, just as I’d prefer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.

lineage_paid_of: 244.14999999999998
inlined lineage_paid_of: 244.14999999999998
regulars_lineage_payable_of: 194.7
youths_lineage_payable_of: 49.45
add floating-point constants: 244.14999999999998
add pennies, then convert to dollars: 244.15&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-7-get-things-out-of-my-head&quot;&gt;Step 7: Get Things Out of My Head&lt;/h2&gt;
&lt;p&gt;I could declare victory, fix the code, confirm that it works, then get on with my life, but if I did that, I’d risk losing valuable information already decaying in my memory. Accordingly, I write things down while it remains fresh in my mind. Here is the updated output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.

lineage_paid_of: 244.14999999999998
inlined lineage_paid_of: 244.14999999999998
regulars_lineage_payable_of: 194.7
youths_lineage_payable_of: 49.45
add floating-point constants: 244.14999999999998
add pennies, then convert to dollars: 244.15

It seems that we should add pennies, then convert to dollars at the last possible moment.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, at least, when I run this script in the future, if the output doesn’t match the conclusion at the end, then I know I need to investigate further. This matches the spirit of the xUnit test libraries, which pride themselves in saying as little as possible when the tests all pass and yelling loudly when there is a failure to investigate.&lt;/p&gt;
&lt;h2 id=&quot;the-final-test-script&quot;&gt;The Final Test Script&lt;/h2&gt;
&lt;p&gt;Here is the current content of &lt;code&gt;test_rounding&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
echo &amp;quot;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.&amp;quot;
echo &amp;quot;&amp;quot;

echo -n &amp;quot;lineage_paid_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::lineage_paid_of&amp;#39;
echo -n &amp;quot;inlined lineage_paid_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::regulars_lineage_payable_of + ProcessMoneySlips::youths_lineage_payable_of&amp;#39;
echo -n &amp;quot;regulars_lineage_payable_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::regulars_lineage_payable_of&amp;#39;
echo -n &amp;quot;youths_lineage_payable_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } },  &amp;quot;extra_prize_funds&amp;quot;: 0 } | ProcessMoneySlips::youths_lineage_payable_of&amp;#39;
echo -n &amp;quot;add floating-point constants: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;194.7 + 49.45&amp;#39;
echo -n &amp;quot;add pennies, then convert to dollars: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;(19470 + 4945) / 100.0&amp;#39;

echo &amp;quot;&amp;quot;
echo &amp;quot;It seems that we should add pennies, then convert to dollars at the last possible moment.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I now have enough information to fix the defect and I have recorded enough information to understand this script two years from now, in case I need to run it.&lt;/p&gt;
&lt;p&gt;And now, before I declare victory, let me remove the parts of the input that each test doesn’t need.&lt;/p&gt;
&lt;h2 id=&quot;the-final-final-test-script&quot;&gt;The Final Final Test Script&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
echo &amp;quot;When an output value is rounded to the nearest penny, that test passes; when it isn&amp;#39;t, that test fails.&amp;quot;
echo &amp;quot;&amp;quot;

echo -n &amp;quot;lineage_paid_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } } } | ProcessMoneySlips::lineage_paid_of&amp;#39;
echo -n &amp;quot;inlined lineage_paid_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19, &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0, &amp;quot;youth&amp;quot;: 1 } } } | ProcessMoneySlips::regulars_lineage_payable_of + ProcessMoneySlips::youths_lineage_payable_of&amp;#39;
echo -n &amp;quot;regulars_lineage_payable_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;regular&amp;quot;: 19 }, &amp;quot;spare&amp;quot;: { &amp;quot;regular&amp;quot;: 0 } } } | ProcessMoneySlips::regulars_lineage_payable_of&amp;#39;
echo -n &amp;quot;youths_lineage_payable_of: &amp;quot;; jq -L &amp;quot;scripts/financials&amp;quot; -n &amp;#39;import &amp;quot;process_money_slips&amp;quot; as ProcessMoneySlips; { &amp;quot;bowlers&amp;quot;: { &amp;quot;full&amp;quot;: { &amp;quot;youth&amp;quot;: 5 }, &amp;quot;spare&amp;quot;: { &amp;quot;youth&amp;quot;: 1 } } } | ProcessMoneySlips::youths_lineage_payable_of&amp;#39;
echo -n &amp;quot;add floating-point constants: &amp;quot;; jq -n &amp;#39;194.7 + 49.45&amp;#39;
echo -n &amp;quot;add pennies, then convert to dollars: &amp;quot;; jq -n &amp;#39;(19470 + 4945) / 100.0&amp;#39;

echo &amp;quot;&amp;quot;
echo &amp;quot;It seems that we should add pennies, then convert to dollars at the last possible moment.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I can fix the defect with confidence.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;You can use the Saff Squeeze even if you don’t have automated tests. It’s enough to do this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Compute the answer and document how to interpret it as “correct” or “incorrect”. If you have to do this manually by clicking, then write a Test Script like it’s 1993.&lt;/li&gt;
&lt;li&gt;Prune irrelevant details from the “test”. Confirm that it continues to fail the same way it did before.&lt;/li&gt;
&lt;li&gt;Inline the action and add this as another “test”. Confirm that it also fails.&lt;/li&gt;
&lt;li&gt;Prune irrelevant details from the new “test”. Convert &lt;code&gt;if&lt;/code&gt; conditions into assertions, which means adding a new, smaller “test” that expects that condition. Document the assertion so that it will be clear to you even when you read it years from now.&lt;/li&gt;
&lt;li&gt;Inline the action or write a smaller “test” for only one part of the action. You can choose. Remember to add these as new “tests”; don’t throw the old ones away.&lt;/li&gt;
&lt;li&gt;Repeat pruning and inlining until the defect becomes obvious.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What matters most to me are these two guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add “tests” as you zoom in on the location of the problem. Don’t throw away the old “tests”. This leaves a record of what you learned. It also leaves a handful of unit “tests” that you can use as inspiration for when you sit down to write actual unit tests in the future. (Eventually. Right?)&lt;/li&gt;
&lt;li&gt;Whenever you think something even vaguely interesting, write it down in or among your “tests”. Add explanatory text to the output if you can; write comments otherwise. It’s no good to anyone in your head; write it down.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Well… almost. Now that I’m writing the article, I notice that this pseudotest includes &lt;code&gt;extra_prize_funds&lt;/code&gt; in the input, even though &lt;code&gt;lineage_paid_of&lt;/code&gt; doesn’t need it. Oops. I’ll remove that when I clean up before moving on.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 19 Dec 2024 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/saff-squeeze-example-1</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/saff-squeeze-example-1</guid>
        
        
        <category>Tutorials</category>
        
      </item>
    
      <item>
        <title>Refactoring Just Enough</title>
        <description>&lt;p&gt;This comment arose recently at &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;The jbrains Experience&lt;/a&gt; in a discussion about whether all software design choices are “like, just my opinion, man”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ve kind of looked at this in the way. That a beginner needs rules because they don’t yet have the experience to judge each situation on its own. I suppose I am in a way asking for a rule to help hone my judgement when I should or might want to refactor.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Indeed, so here are some rules that I’ve found helpful over the years:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;refactor only when you’re about to touch that part of the code&lt;/li&gt;
&lt;li&gt;refactor only enough to support what you need to do now (Kent Beck’s “make the change easy, then make the easy change”)&lt;/li&gt;
&lt;li&gt;leave SMELL/REFACTOR comments any time you notice a smell or refactoring and don’t intend to address it now, due to some other rule&lt;/li&gt;
&lt;li&gt;Clean Up Before Moving On, with preferably a very specific list of things to clean up or a time limit otherwise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These rules helped me build the habit of “clean the kitchen as you go” refactoring while avoiding the trap of polishing the stone beyond what’s needed. Even so, I still polished some stones too much and didn’t clean the kitchen enough.&lt;/p&gt;
&lt;p&gt;I think that particularly Advanced Beginners need to over-polish some stones in order to learn where to draw a more-balanced boundary. I also think that the typical time pressure of an industrial-strength project situation makes it very difficult for programmers to allow themselves (and each other) to over-polish some stones. These two things together trap programmers in the Advanced Beginner stage.&lt;/p&gt;
&lt;h1 id=&quot;you-must-know-when-to-break-the-rules&quot;&gt;You Must Know When to Break the Rules&lt;/h1&gt;
&lt;p&gt;I don’t follow these rules very carefully all the time any more. I tend to trust myself to refactor just enough, although if I notice that I’m starting to retreat into refactoring because I’m afraid to add features or fix defects—and this &lt;em&gt;does&lt;/em&gt; still happen from time to time—then I know which rules to reach for. I tend to prefer to Clean Up Before Moving On, because I have observed myself rushing to finish features (from excitement, usually, not time stress) and so at this specific time I tend to have overlooked refactoring the most.&lt;/p&gt;
</description>
        <pubDate>Fri, 21 Jun 2024 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/refactoring-just-enough</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/refactoring-just-enough</guid>
        
        
        <category>Programming Without Blame</category>
        
      </item>
    
      <item>
        <title>TDD: You&apos;re Probably Doing It Just Fine</title>
        <description>&lt;p&gt;I’d like to share a few little points to help you or someone you care about through their day.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can write good code without TDD.&lt;/li&gt;
&lt;li&gt;Even the act of trying to write one test is already enough to clarify your thinking about what the system (or some part of it) ought to do.&lt;/li&gt;
&lt;li&gt;You don’t have to do TDD 100% all the time perfectly in order to benefit from doing it some of the time and pretty well.&lt;/li&gt;
&lt;li&gt;You might find tests helpful when it comes time to change the code after you’ve written it the first time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I fear that some people feel like they’re Not Doing It Right when they’re doing actually quite good work. Even so, I’d bet my own money that, on average, you’d benefit from practising more TDD than you do now.&lt;/p&gt;
&lt;p&gt;TDD definitely doesn’t work if you turn learning into a guilt/shame spiral by focusing on what you don’t yet know and what you don’t yet do.&lt;/p&gt;
&lt;h1 id=&quot;some-clarification&quot;&gt;Some Clarification&lt;/h1&gt;
&lt;p&gt;If that was enough for you, then stop. If you’d like a little more detail, then read on.&lt;/p&gt;
&lt;h2 id=&quot;point-1&quot;&gt;Point 1&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;You can write good code without TDD.&lt;/strong&gt; I wanted to learn about Test-First Programming (as we called it then) because I grew tired of the mistakes I was making. It seemed like I shipped defects every week and when I fixed one defect, I created two more. This provided a natural motivation to try writing tests before writing production code. The rest is history.&lt;/p&gt;
&lt;p&gt;Just because I needed it then and still appreciate it now doesn’t mean that you need TDD to write good code. Remember: the goal is to write good code for whatever “good” means to us in the moment. In 1999, I wanted the “it actually works!” kind of “good”, although over time that expanded towards the “I don’t hate it after I’ve written it” kind of “good” combined with the “Pretty much anyone who needs to change it can change it pretty confidently” kind of “good”. I continue to be able to write that kind of “good” code, partly because of the lessons I learned from practising TDD and partly because when I get into trouble, writing some tests first tends to get me out of that trouble.&lt;/p&gt;
&lt;p&gt;Even so, you might care about different kinds of “good” and you might make different kinds of mistakes, so maybe TDD isn’t what you need right now. If you don’t need it, then don’t feel bad about not doing it. &lt;strong&gt;And ignore anyone who tells you that not practising TDD amounts to some kind of malpractice or—universe help us—“unprofessionalism”.&lt;/strong&gt; What bullshit!&lt;/p&gt;
&lt;p&gt;If you don’t know how to write low-defect code that’s also inexpensive to change in the future, then you should probably learn how to do that. And maybe TDD would help, but if you find another way, then go for it!&lt;/p&gt;
&lt;h2 id=&quot;point-2&quot;&gt;Point 2&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Even the act of trying to write one test is already enough to clarify your thinking about what the system (or some part of it) ought to do.&lt;/strong&gt; I’m continually amazed at what happens when I merely try to write one test from beginning to end in all its gory details, especially when it’s the first test for an unfamiliar feature or feature area in the system. &lt;strong&gt;Even if I never run that test&lt;/strong&gt;, the mere act of writing it leads me to clarify so many things floating around in my mind that any inaccuracies or unclear parts become magnified to the point that I can’t ignore them. When I write such a test using pen and paper, about half the page ends up scratched out and rewritten. And that’s the point! Writing even just one test, whether you automate it or not, whether you write any more tests or not, is already enough to help you see what’s unclear in your mind about what you intend to build. Just try it!&lt;/p&gt;
&lt;p&gt;Writing one test before you to try to write production code doesn’t mean committing to practising TDD perfectly all the time. Often it’s enough just to write one test, and then enough becomes clear that you feel confident that you can take it from there. Remember: if you get into trouble, then writing more tests and earlier might help you get out of that trouble!&lt;/p&gt;
&lt;h2 id=&quot;point-3&quot;&gt;Point 3&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;You don’t have to do TDD 100% all the time perfectly in order to benefit from doing it some of the time and pretty well.&lt;/strong&gt; I got great benefits from practising test-first programming the first time I did it “in anger” on a real project at my day job over the period of about 10 days. I barely knew what I was doing. I was slow. I was literally changing as little as four lines of code &lt;em&gt;per hour&lt;/em&gt; half the time, because my tests were so slow! And it still helped me redo three months of flailing around in 9, 14-hour days. (If it weren’t crunch time and if I hadn’t put myself in a corner, that could have been three relaxed weeks. Live and learn!) I was writing horrifying integrated tests and I was already falling for the scam. My design was tangled in spots in ways that I would notice in an instant today. &lt;strong&gt;And it still went much better than what I’d been doing before.&lt;/strong&gt; That’s the point: you can reap benefits from writing the test first even before you know how to do it well, so let yourself do it as well as you can. Ask questions. Just keep going.&lt;/p&gt;
&lt;p&gt;You won’t know what you’re doing until you’ve written about 2000 tests, so get started!&lt;/p&gt;
&lt;h2 id=&quot;point-4&quot;&gt;Point 4&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;You might find tests helpful when it comes time to change the code after you’ve written it the first time.&lt;/strong&gt; Senior programmers routinely tell me that they want to throw their tests away after they’ve written the production code. I still don’t really understand why they accept remaining imprisoned by design choices of the past, especially when I also hear them routinely complain about how difficult it is to work in legacy code and how nice it would be if they could just write it all over again.&lt;/p&gt;
&lt;p&gt;I want to be able to refactor and I tend to find that safer when I have tests, even if I have to refactor the tests as well. If I don’t have helpful tests, I can use microcommits as a way to limit the damage of making a mistake while refactoring. Even so, I &lt;em&gt;built&lt;/em&gt; my refactoring skill by feeling free to move code around and break things, and &lt;strong&gt;I don’t know how I would have felt that freedom without tests to sound the alarm when I made a wrong move&lt;/strong&gt;. If you have another way to create a safe learning environment for changing the design decisions you regret, then you should do that, but I found tests indispensable while I was developing my skills and judgment.&lt;/p&gt;
&lt;h1 id=&quot;a-conclusion&quot;&gt;A Conclusion&lt;/h1&gt;
&lt;p&gt;Just because you’d like to do it better doesn’t mean you’re doing it &lt;em&gt;wrong&lt;/em&gt; or even &lt;em&gt;poorly&lt;/em&gt;. And even if you are doing it poorly now, repetition leads to ease leads to chunking and you’ll gradually do it better. For most people most of the time, their brain doesn’t give them a choice: it gathers experience and improves skill, even when they don’t notice it happening. It is enough to keep practising, and when it doesn’t go well and you need to stop, don’t worry about it. Just start again.&lt;/p&gt;
</description>
        <pubDate>Mon, 25 Mar 2024 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/tdd-youre-probably-doing-it-just-fine</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/tdd-youre-probably-doing-it-just-fine</guid>
        
        
        <category>Programming Without Blame</category>
        
        <category>Not Just Coding</category>
        
      </item>
    
      <item>
        <title>TDD: For Those Who Don&apos;t Know How to Design Software</title>
        <description>&lt;p&gt;I’ve been reading &lt;a href=&quot;https://substack.com/@kentbeck&quot;&gt;Kent Beck’s writing on Substack&lt;/a&gt; and on the occasion of the death of &lt;a href=&quot;https://en.wikipedia.org/wiki/Niklaus_Wirth&quot;&gt;Niklaus Wirth&lt;/a&gt;, he shared part of a conversation he’d had with the professor when Kent had arranged to sit next to him on the flight home from a conference they’d both spoken at.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Extreme Programming was just starting to crackle &amp;amp; pop, so I’m sure I was a bit over-enthusiastic. After I had given an impassioned explanation of incremental design &amp;amp; refactoring, he paused, looked at me with those eyes, and, “I suppose that’s all very well if you don’t know how to design software.” Mic. Drop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two thoughts immediately came to mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;He’s not wrong.&lt;/li&gt;
&lt;li&gt;I wish he hadn’t framed that with such blaming language!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since I became acutely aware of my own tendency to blame others, I started seeing it everywhere. As part of changing my own habits, I’ve spent much energy both analyzing and reframing comments like these with the goal of making them “more helpful” in some way to the people who might read them. I would not like someone reading or hearing the professor’s comment to become discouraged or to see TDD as something merely for software designers who don’t know what they’re doing.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Even so, once I let my immediate feelings about these words settle, I noticed a more hopeful reframing of the professor’s words, without the need even to change them. Indeed, &lt;strong&gt;TDD can help people who don’t (yet) know (everything they need to know about) how to design software&lt;/strong&gt;. I think this is true of Evolutionary Design more generally, whether we guide our incremental design with tests or some other way.&lt;/p&gt;
&lt;p&gt;And while it would be generally easy to interpret this as a professor looking down their nose at “lowly students”, I can interpret it as &lt;strong&gt;a sensible strategy&lt;/strong&gt; for those of us, the “mere mortals”, who don’t always and immediately see the right design before we sit down to write code.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; Or the ones who are forced to write “better”-designed code alongside “worse”-designed code that is nevertheless too profitable to throw away. Or the ones who happen at the moment to be struggling with a complicated or difficult problem and need to spend their precious brain energy on &lt;em&gt;that&lt;/em&gt;—the ones who don’t have as much energy left over to conceive of an obviously sensible design for the code that solves the problem. I’d say there are several reasons why one might choose to practise Evolutionary Design—even TDD—&lt;strong&gt;that reflect a (temporary) need to compensate for not knowing (exactly) how to design (this particular piece of) software (just yet)&lt;/strong&gt;, rather than some permanent(-seeming) lack of ability to design software.&lt;/p&gt;
&lt;p&gt;Moreover, for the ones of you who look at architects or senior programmers and marvel at how quickly they produce solutions, who then feel inadequate or incapable of doing what they do—think again! You might be able to &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;use Evolutionary Design in general and TDD in particular to build&lt;/a&gt; the very skills that you worry you don’t have or can’t develop.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; I made TDD a centerpiece of how I developed my skill to design software and I feel fairly confident that you can, too!&lt;/p&gt;
&lt;p&gt;These thoughts change the way I interact with Professor Wirth’s comment.&lt;/p&gt;
&lt;p&gt;Indeed, there are times when I sit down to write code and I know enough about what I’m trying to do and I’m working in an environment that I know well enough and I’m interfacing with technology that I know well enough and a beautifully modular design arises in my mind without much effort. I like that feeling. And when that happens, I don’t waste my time writing the code test first. Indeed, I might not write many tests at all! Or, if I’m feeling a bit uncertain, I’ll practise test-first programming, where I write the tests first, but only as a way to detect mistakes early while I type into the computer the design that’s already fully-formed in my head. And when I do these things, I feel productive and fast and even &lt;em&gt;powerful&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I got there, I’m quite sure, at least in part by &lt;strong&gt;redesigning software &lt;em&gt;a lot&lt;/em&gt;&lt;/strong&gt;. Most of that came in the form of refactoring: improving the design of existing code. (And sometimes not improving, but changing design to understand better why it’s not getting any better.) And &lt;strong&gt;that refactoring became much safer&lt;/strong&gt; because I was building a habit of writing tests that helped me notice mistakes sooner. And &lt;strong&gt;building that habit was made easier&lt;/strong&gt; by volunteering to write those tests first, when it became significantly more likely for me to remember to write them. Could I have got there another way? Maybe, but it’s enough for me to say that this path got me there, and I’d be shocked if I were unique in that way.&lt;/p&gt;
&lt;p&gt;In addition, I don’t feel particularly inferior on the days where it’s not so clear and I stumble around and find myself refactoring relentlessly to reach an unexpected design that I feel satisfied with. On the contrary, &lt;strong&gt;I feel supported&lt;/strong&gt; by a practice that helps me get to “a good place”, even when I can’t see the finish line in my mind at the start, when the Insight Fairies don’t visit, when I am confronted with strange technology or a thorny problem or gnarly legacy code. &lt;strong&gt;When I’m not sure what to do&lt;/strong&gt; the moment I sit down—which is what happens most of the time—then I’m happy to know that it’s enough to stick with the three safe moves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;write a failing test&lt;/li&gt;
&lt;li&gt;remove some duplication&lt;/li&gt;
&lt;li&gt;improve a name&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Does this mean that I don’t know how to design software? Would Professor Wirth look down his nose at me? I’ll never know. And either way, I don’t mind.&lt;/p&gt;
&lt;p&gt;This is how I produce better results than I would otherwise produce. This is how I get more out of my knowledge. This is how I continue to develop valuable experience. And I think that works quite well for me.&lt;/p&gt;
&lt;p&gt;It makes me wonder how Professor Wirth got there, but it doesn’t fill me with self-doubt about how I got here.&lt;/p&gt;
&lt;p&gt;And it might help you, too.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I’m not merely manufacturing drama here. I routinely help programmers work through feelings of inadequacy and self-doubt as part of managing their careers. &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;After several years of doing this&lt;/a&gt;, I’m forced to conclude that a significant segment of the population takes comments like these to heart, they feel hurt, and they need support.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I’ll bet that at least one of you reading this is screaming “Strawman! Strawman!” I understand. No, I don’t think this is exactly what Professor Wirth meant by his comment. I don’t have the context; I didn’t know the man’s habits; I’m not trying to guess what he meant. I’m concerned with how innocent bystanders reading this comment are likely to think of it. I’ve seen enough people internalize remarks like these in a way that creates lasting damage. That’s what gives me the idea to write these words today.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;If you like the “growth mindset”/“fixed mindset” framing, then you can think of Evolutionary Design as a way to work that reflects a growth mindset by developing both knowledge and facility in software design, rather than assuming that you “should have known all this by now”.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 08 Jan 2024 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/tdd-for-those-who-dont-know-how-to-design-software</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/tdd-for-those-who-dont-know-how-to-design-software</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
        <category>Evolutionary Design</category>
        
        <category>Programming Without Blame</category>
        
      </item>
    
      <item>
        <title>A Guard Clause Is Maybe a Tiny Parser</title>
        <description>&lt;h1 id=&quot;overture&quot;&gt;Overture&lt;/h1&gt;
&lt;p&gt;You’ve probably seen code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (condition)
    ...more code...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ve probably seen code that looks like this, and then after you understand it, you think of it more like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (protective_condition)
    ...now it&amp;#39;s safe to run this code...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ve almost certainly considered expressing this intention more directly using a Guard Clause: a structural pattern that emphasizes the protective intent of the condition. Now you have code that looks more like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!protective_condition) return;

// Whew! The coast is clear.
...more code...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I already really prefer this code, because it communicates the protective intent of the condition. This code’s structure screams “&lt;strong&gt;WARNING!&lt;/strong&gt; Don’t even &lt;em&gt;think&lt;/em&gt; about trying to handle this request unless these critical preconditions are met! If you don’t meet these critical preconditions, but you run this code, there is no warranty, express nor implied. You’re on your own. Good luck.”&lt;/p&gt;
&lt;p&gt;This sounds like the kind of warning I’d like to notice easily as I wander through the code. The Guard Clause structure draws attention to that kind of warning.&lt;/p&gt;
&lt;p&gt;If you’re satisfied, then stop here.&lt;/p&gt;
&lt;h1 id=&quot;struggle&quot;&gt;Struggle&lt;/h1&gt;
&lt;p&gt;Sometimes we want to extract the “more code” and isolate it from the Guard Clause, because that makes the overall code less expensive to understand how to change safely, accurately, and confidently. That often leads to code that looks like this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;void onBarcode(String barcode) {
    if (barcode.isEmpty()) {
        display.displayEmptyBarcodeMessage();
        return;
    }

    whatDoIEvenCallThis(barcode);
}

void whatDoIEvenCallThis(String barcode) {
    Price price = catalog.findPrice(barcode);
    if (price == null) {
        display.displayProductNotFoundMessage(barcode);
    }
    else {
        display.displayPrice(price);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ve taken this example from the Point of Sale system that I typically offer as a project in my training courses. I notice two things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I don’t quite know what to call this method. I wish I could also call it &lt;code&gt;onBarcode()&lt;/code&gt;, but Java won’t let me.&lt;/li&gt;
&lt;li&gt;When I invoke &lt;code&gt;whatDoIEvenCallThis()&lt;/code&gt;, I have to remember that it doesn’t properly defend against the invalid input of an empty &lt;code&gt;String&lt;/code&gt;, which makes the code more expensive to understand how to change safely, accurately, and confidently.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What do programmers often do in this situation? I see them do this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public void onBarcode(String barcode) {
    if (barcode.isEmpty()) {
        display.displayEmptyBarcodeMessage();
        return;
    }

    handleValidBarcode(barcode);
}

private void handleValidBarcode(String barcode) {
    Price price = catalog.findPrice(barcode);
    if (price == null) {
        display.displayProductNotFoundMessage(barcode);
    }
    else {
        display.displayPrice(price);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The name “handle valid barcode” at least tries to signal to the human reader that the method only operates on “valid” barcodes, but it doesn’t help the programmer understand what “valid” means in this context. We could try a more-precise name, but then we’d duplicate the Guard Clause condition in one method with the name of a different method. This might work fine while the methods remain in the same class, but I’d bet my own money on this eventually becoming Spooky Action At a Distance. It’s only a matter of time.&lt;/p&gt;
&lt;p&gt;Marking &lt;code&gt;handleValidBarcode()&lt;/code&gt; as &lt;code&gt;private&lt;/code&gt; makes it sufficiently difficult to invoke the method out of its context, but at the price of nailing the method fast to its context. It reduces options for moving code around. I’d bet my own money that someone will eventually &lt;a href=&quot;https://blog.jbrains.ca/permalink/ask-why-but-never-answer&quot;&gt;scream “WHY?!?!?”&lt;/a&gt; when they want to write a test for the future version of this code and learn that they can’t, because it’s not &lt;code&gt;public&lt;/code&gt;. (Well… that doesn’t &lt;em&gt;stop&lt;/em&gt; them, but it forces them to jump through pointless and confusing hoops. Every path forward from here causes pain and suffering.)&lt;/p&gt;
&lt;p&gt;There has to be a better way.&lt;/p&gt;
&lt;h1 id=&quot;parser&quot;&gt;Parser&lt;/h1&gt;
&lt;p&gt;I prefer to invoke the delightful principle &lt;a href=&quot;https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/&quot;&gt;“Parse, Don’t Validate”&lt;/a&gt; here, so that the type system makes it clear that by the time the data reaches &lt;code&gt;handleValidBarcode()&lt;/code&gt;, we can trust it to be valid, even when we don’t know what “valid” means.&lt;/p&gt;
&lt;p&gt;The strategy involves parsing the &lt;code&gt;String&lt;/code&gt; into a value type that carries the information “No, really, this value is totally valid. No need to trust me; I have the receipts.” We don’t even need to struggle to find a name for it: there’s a clue in the name of the argument to &lt;code&gt;onBarcode()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;class Barcode {
    public Either&amp;lt;EmptyBarcode, Barcode&amp;gt; parse(String text) {
        return text.isEmpty()
            ? Either.left(EmptyBarcode.instance())
            : Either.right(new Barcode(text));
    }
    
    private final String text;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you find &lt;code&gt;Either&lt;/code&gt; too heavy-handed, then you could use &lt;code&gt;Maybe&lt;/code&gt; or even throw an exception. The three options are equivalent enough that I would feel comfortable using whichever one you preferred.&lt;/p&gt;
&lt;p&gt;Now that we have this parsing behavior, we could rewrite &lt;code&gt;onBarcode()&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public void onBarcode(String text) {
    Barcode.parse(text).map(
        // A bit ugly, so maybe use functions
        // instead of actions/Consumers/void
        barcode -&amp;gt; {
            handleValidBarcode(barcode);
            return null;
        }
    ).orElseRun(
        ignored -&amp;gt; display.displayEmptyBarcodeMessage()
    );
}

private void handleValidBarcode(Barcode barcode) {
    Price price = catalog.findPrice(barcode.text());
    if (price == null) {
        display.displayProductNotFoundMessage(barcode.text());
    }
    else {
        display.displayPrice(price);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here I’m using Vavr’s version of &lt;code&gt;Either&lt;/code&gt;, which might look strange to some readers, especially when combined with methods that return &lt;code&gt;void&lt;/code&gt;. Maybe you’d prefer a plain Java version that signals parsing failure by throwing an exception.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public void onBarcode(String text) {
    try {
        handleValidBarcode(Barcode.parse(text));
    }
    catch (EmptyBarcodeException handled) {
        display.displayEmptyBarcodeMessage();
    }
}

private void handleValidBarcode(Barcode barcode) {
    Price price = catalog.findPrice(barcode.text());
    if (price == null) {
        display.displayProductNotFoundMessage(barcode.text());
    }
    else {
        display.displayPrice(price);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whichever you choose, you might then prefer to refactor the rest of the code base to operate on &lt;code&gt;Barcode&lt;/code&gt; values instead of the raw &lt;code&gt;String&lt;/code&gt;, at least until you actually need the raw &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;judgment&quot;&gt;Judgment&lt;/h1&gt;
&lt;p&gt;Which do you prefer? I know: it depends on the context. You can’t really know until you try it. In a small code base, the parser feels like overkill, but as the code base grows, it becomes increasingly valuable to know when the value in your hands is trustworthy or not. Indeed, that was the point of the protective condition at the very beginning of our journey: to draw attention to the fact that that text was not yet trustworthy, so the rest of the system shouldn’t even try to process it until it knows that the barcode text is not empty. The Guard Clause takes one significant step in the direction of expressing that intent more clearly. The Parser makes the matter nearly impossible to ignore, especially when the Parser returns an &lt;code&gt;Either&lt;/code&gt; value or throws a compile-time type-checked exception.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;A Guard Clause is maybe a tiny parser, so try replacing it with a parser. Once you become comfortable with this progression of refactorings—from protective condition to Guard Clause to Parser—you can do it effortlessly the moment that the simple protective condition becomes a noticeable irritation; before then, you can safely let it be as it is. This is the awesome power of any refactoring: once you know how to do it well enough, you can trust yourself (and others) much more to do it, but only when it becomes truly helpful.&lt;/p&gt;
</description>
        <pubDate>Wed, 20 Dec 2023 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-guard-clause-is-maybe-a-tiny-parser</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-guard-clause-is-maybe-a-tiny-parser</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
        <category>Microtechniques</category>
        
      </item>
    
      <item>
        <title>Which Kinds of Tests Should I Write? Revisited</title>
        <description>&lt;p&gt;I see so many programmers tying themselves up in knots, trying to find “the right” testing strategy. I’d like to offer them a simple idea intended to make at least one of these knots loosen itself and disappear.&lt;/p&gt;
&lt;p&gt;This issue shows up in a few forms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which is better: TDD or BDD?&lt;/li&gt;
&lt;li&gt;Which should I write: functional tests or unit tests?&lt;/li&gt;
&lt;li&gt;The testing pyramid is wrong and I have invented a new shape for tests that will solve all your problems!&lt;/li&gt;
&lt;li&gt;“Beware the Integrated Tests Scam!” (wait… that one is my fault)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;a-true-but-useless-answer&quot;&gt;A True, But Useless Answer&lt;/h1&gt;
&lt;p&gt;Write whatever tests make you happy. Test until fear is transformed into boredom. Do what seems to help until it doesn’t seem to help any more, then stop. It’ll be fine.&lt;/p&gt;
&lt;p&gt;I genuinely believe in this answer, but it doesn’t really help a confused programmer (or technical leader) feel comfortable about what they’re doing, now, does it?&lt;/p&gt;
&lt;h1 id=&quot;an-insufficient-but-more-useful-answer&quot;&gt;An Insufficient, But More-Useful Answer&lt;/h1&gt;
&lt;p&gt;Among these apparent dilemmas and conundrums, we find the people who claim that they’d rather write Customer Tests than Programmer Tests. After all, they want to please their Customer&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, so it makes sense to focus on Customer Tests. These seem much more important than Programmer Tests.&lt;/p&gt;
&lt;p&gt;Oh… you don’t use these terms? No problem. You might know Customer Tests as something like “functional tests” or “end-to-end tests” or “Cucumber tests” or “Selenium tests” or “Capybara tests” or whatever the cool kids use these days. Similarly, you might know Programmer Tests by names such as “unit tests” or “microtests”. These terms don’t correspond perfectly, but when we compare what I mean by “Customer Tests” to what they usually mean by “functional tests”, these things turn out in practice almost always to be very close to equivalent. Something similar happens for “Programmer Tests” and “unit tests”. I’ll call them by my preferred names, because I specifically mean to classify tests by their purpose and not by their scope nor their tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I see no dilemma here&lt;/strong&gt;, except perhaps the notion that they pay us to deliver features and not write tests, therefore we can’t write all the tests we want, and so we must choose carefully. (Even that’s not quite right, but it’s close enough for now.)&lt;/p&gt;
&lt;p&gt;Customer Tests help me assure the Customer that we have understood what they’ve asked for and that we will deliver what they consider “valuable” for their particular meaning of “value”.&lt;/p&gt;
&lt;p&gt;Programmer Tests help me assure myself and my fellow programmers that the code does what we thought we asked it to do.&lt;/p&gt;
&lt;p&gt;When we try to use the same set of tests for both purposes, all kinds of dysfunctions follow. Notably, senior technical staff get into heated debates about which kinds of tests to write. (That’s how we got here.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Therefore, let us choose the kind of test that corresponds to our current needs&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I lean on Customer Tests when I want more confidence that we’re tackling the problems that our Customer wants us to tackle. I lean on Programmer Tests when I want to understand just what the hell is going on with this code.&lt;/p&gt;
&lt;p&gt;That’s it.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I use Customer in the XP sense of the term. I also use it in the singular, even though very often, we have more than one Customer. If you prefer to think of the term as plural in your mind, that works fine and doesn’t change my points here.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 17 Sep 2023 19:41:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/which-kinds-of-tests-should-i-write-revisited</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/which-kinds-of-tests-should-i-write-revisited</guid>
        
        
        <category>Programming Without Blame</category>
        
      </item>
    
      <item>
        <title>Revealing Intent: A Tiny Example</title>
        <description>&lt;p&gt;By now you’ve probably heard of &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;Four Elements of Simple Design&lt;/a&gt;, among which you’ll find this suggestion: &lt;strong&gt;reveal intent&lt;/strong&gt;. You’ve probably also read articles about how to do this, many of which feel entirely subjective and seem to beg their own question: if it’s enough to improve names, then I need good judgment to improve names; how do I develop that judgment?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.jbrains.ca/permalink/test-driven-development-as-pragmatic-deliberate-practice&quot;&gt;Deliberate practice&lt;/a&gt;. Repetition. Inviting the loving criticism of others.&lt;/p&gt;
&lt;p&gt;Examples.&lt;/p&gt;
&lt;h1 id=&quot;an-example&quot;&gt;An Example&lt;/h1&gt;
&lt;p&gt;I wanted to redeploy a simple web site to Netlify using the &lt;code&gt;netlify-cli&lt;/code&gt; tool. I typed this:&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;$ netlify deploy --prod&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, I’d rather that switch read &lt;code&gt;production&lt;/code&gt;, but that’s not what I wanted to point out today.&lt;/p&gt;
&lt;p&gt;When I did this, &lt;code&gt;netlify-cli&lt;/code&gt; informed me that there was no Netlify site linked to this project’s repository and asked me whether I’d like to link one. Of course I would! I answered its questions, resulting in &lt;code&gt;netlify-cli&lt;/code&gt; updating a file in my repository.&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;$ git diff
diff --git a/.gitignore b/.gitignore
index c1a6e33..d30de63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
 www/
 .sass-cache
 .jekyll-metadata
+
+# Local Netlify folder
+.netlify&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I will risk sounding like &lt;em&gt;that guy&lt;/em&gt;. Please forgive me.&lt;/p&gt;
&lt;p&gt;This comment strikes me as very similar to…&lt;/p&gt;
&lt;pre class=&quot;c&quot;&gt;&lt;code&gt;// Increment x by 1
x = x + 1;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;reveal-intent-by-asking-why&quot;&gt;Reveal Intent by Asking “Why?!”&lt;/h1&gt;
&lt;p&gt;I learned this trick a long time ago and it rarely lets me down. When I want to reveal intent, I ask “why?!” and replace existing words with the answer to that question. Let’s try it.&lt;/p&gt;
&lt;p&gt;Why do I want to ignore the local Netlify folder (as opposed to some other folder)? Because this project isn’t forced to deploy to Netlify; it could deploy anywhere.&lt;/p&gt;
&lt;p&gt;Sometimes asking “why?!” doesn’t suffice. In this case, I’m looking for an intention-revealing name and the current name describes the implementation details instead of the purpose. Perhaps I need another question.&lt;/p&gt;
&lt;h1 id=&quot;reveal-intent-by-asking-what&quot;&gt;Reveal Intent by Asking “What?!”&lt;/h1&gt;
&lt;p&gt;I learned this trick a long time ago, too, and it bails me out when the “why?!” question lets me down. When I want to name something according to its purpose instead of its implementation, I ask “what is this, &lt;em&gt;really&lt;/em&gt;?!” with a little bit of “…and don’t say what’s already there!”&lt;/p&gt;
&lt;p&gt;What is this Netlify local folder nonsense?! I guess it’s data about where I have deployed this project. One might call that a “project deployment details folder”. Not bad.&lt;/p&gt;
&lt;p&gt;I might not stop here forever, but, following the rule “I Type What I Say”, I type what I said.&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;diff --git a/.gitignore b/.gitignore
index c1a6e33..d30de63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
 www/
 .sass-cache
 .jekyll-metadata
+
+# Deployment details
+.netlify
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Better. Ship it.&lt;/p&gt;
&lt;h1 id=&quot;really&quot;&gt;Really?!&lt;/h1&gt;
&lt;p&gt;Yes. What happens now, in five years, when I deploy this project somewhere other than Netlify? (These places have a habit of disappearing or starting to charge exorbitant fees or something. Ask TextDrive and Heroku.) When I see the word “deployment” referring to &lt;code&gt;.netlify&lt;/code&gt;, it becomes much more likely that I’ll volunteer to update the project consciously, rather than leaving cruft to accumulate. Imagine if, in 20 years, I’m wondering what the hell “Netlify” was for. “I haven’t used Netlify since 2028! I guess I can finally delete that!”&lt;/p&gt;
&lt;p&gt;You scoff, but how much of your legacy code boils down to everyone forgetting what the hell “Netlify”—or something like it—was for?&lt;/p&gt;
&lt;p&gt;Any little thing that helps me delete obsolete code delays the onset of legacy code by precious hours or days. And when legacy code hurts you, you’ll do almost anything to make the pain a little duller.&lt;/p&gt;
</description>
        <pubDate>Tue, 05 Sep 2023 09:03:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/revealing-intent-a-tiny-example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/revealing-intent-a-tiny-example</guid>
        
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Refactoring Test Doubles: From Stubs to Parsing</title>
        <description>&lt;aside&gt;
I considered calling this article “Stubs Aren’t Parsers”, in the grand tradition of &lt;a href=&quot;https://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;“Mocks Aren’t Stubs”&lt;/a&gt; and even “Stubs Aren’t Mocks” (which I never wrote, but wanted to). I don’t love the blaming tone of that title, even though it might feel catchy and &lt;a href=&quot;https://www.amazon.com/Made-Stick-Ideas-Survive-Others-ebook/dp/B000N2HCKQ?_encoding=UTF8&amp;amp;qid=1688552302&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=jbrains.ca-20&amp;amp;linkId=40eae497bf4ee39d1706d043b781c655&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;sticky&lt;/a&gt;, so I’ve gone for a more-boring, less-blaming title.
&lt;/aside&gt;
&lt;p&gt;In his “The Hidden Cost of Mockito”&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, Lars Eckart presents an example in Java of refactoring code in a way that simplifies using Mockito in the corresponding unit tests. His example illustrates very nicely one of two helpful options for refactoring in this situation; I wanted to write this article to describe the other. I imagine that we could find even more helpful refactoring options than these two, but two options seem to me like a helpful place to start.&lt;/p&gt;
&lt;h1 id=&quot;not-refactoring-away-from-test-doubles&quot;&gt;Not “Refactoring Away From Test Doubles”&lt;/h1&gt;
&lt;p&gt;First, let me clarify this point immediately: &lt;strong&gt;I’m not criticizing Mockito nor test doubles (mock objects) in this article&lt;/strong&gt;. I don’t offer you this an example of refactoring away from test doubles, but rather as an example of removing duplication, which just happens to result in removing some test doubles. Both of these statements are true:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just because they’re test doubles, doesn’t mean they’re bad and we ought to try to eliminate them.&lt;/li&gt;
&lt;li&gt;Just because they’re test doubles, doesn’t mean they’re good and we ought to use them everywhere all the time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Instead, I offer this as an example of removing duplication and the duplication happens to be in stubs and the resulting design doesn’t need as many stubs.&lt;/p&gt;
&lt;h1 id=&quot;the-plan&quot;&gt;The Plan&lt;/h1&gt;
&lt;p&gt;We start with tests that stub queries for the detailed data they need, since the Subject Under Test (a function) takes an interface as its only parameter. This makes the tests slightly annoying, because of the &lt;strong&gt;indirect and noisy code that gets in the way of specifying the input of the test&lt;/strong&gt;. We see duplication in the stubs, and in particular, &lt;strong&gt;duplication of irrelevant details&lt;/strong&gt; between the tests: I start noticing that I care only about the different input values to check and not where they come from.&lt;/p&gt;
&lt;p&gt;We extract a smaller function whose parameter is &lt;strong&gt;a Whole Value whose component values combine the return values of the various stubs&lt;/strong&gt;. This makes it easier to provide input directly to the test by creating the Whole Value directly without needing stubs. This leaves behind code that we might or might not judge as Too Simple to Break. It also opens up the opportunity for future refactorings that simplify the parts of the design that lie closer to the application framework boundary.&lt;/p&gt;
&lt;p&gt;I consider this another example of the pattern of replacing “Supplier of T” with “T”, which simplifies the production code a little and tests even more than that. This pattern &lt;strong&gt;guides us towards extracting more Context-Independent Code&lt;/strong&gt;, which requires less effort to test and understand, which offers more opportunities for reuse, and which requires less effort to adapt to a new context.&lt;/p&gt;
&lt;p&gt;I think of this as an easy refactoring, low on risk, but high on reward. Since it’s easy, I tend to perform this refactoring early and aggressively. I don’t remember the last time I regretted performing it.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/an-example-sticker.png&quot; /&gt;
&lt;figcaption&gt;
Source: Brian Marick, &lt;a href=&quot;http://www.exampler.com/propaganda/&quot; class=&quot;uri&quot;&gt;http://www.exampler.com/propaganda/&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h1 id=&quot;start-here&quot;&gt;Start Here&lt;/h1&gt;
&lt;p&gt;Let us start with this typical-looking Java code that handles an HTTP request.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;// Library/framework types that we can&amp;#39;t refactor
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;

class SignatureValidator {
    // Other details intentionally left out
    
    public void validateSignature(HttpHeaders headers) {
        if (headers.getHeaderString(DIGEST) == null 
           || headers.getHeaderString(SIGNATURE) == null) {
            ...
        } else {
            validateDigestHeader(headers);
            validateSignatureHeader(headers);
        }
    }

    private Map&amp;lt;String, String&amp;gt; getLowerCaseRequestHeaders(
        MultivaluedMap&amp;lt;String, String&amp;gt; requestHeaders) {
        
        final Map&amp;lt;String, String&amp;gt; lowerCaseRequestHeaders 
            = new HashMap&amp;lt;&amp;gt;();

        requestHeaders.forEach((key, value) -&amp;gt;
            lowerCaseRequestHeaders.put(
                key.toLowerCase(), requestHeaders.getFirst(key)
            )
        );

        return lowerCaseRequestHeaders;
    }
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing about this production code makes me vomit, but I see a few signals that capture my attention:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checking properties of a value for &lt;code&gt;null&lt;/code&gt; usually means special-case handling of “invalid arguments”. This tends to become tangled with the code that processes valid arguments, making both paths more annoying to test and understand.&lt;/li&gt;
&lt;li&gt;The names of the functions &lt;code&gt;validate*Header(headers)&lt;/code&gt; give me the feeling that there will be more-complicated “validation” in the future, and the programmers will bash it over the head to fit the pattern of “validate blah-blah header”.&lt;/li&gt;
&lt;li&gt;Duplication in the names between a higher-level function named “validate signature” and a lower-level function named “validate signature” signal a missing or unnamed idea. Leaving this idea unnamed or unidentified tends to cause us to refer to slightly different things with the same words. The confusion usually spreads through both the code and the project community.&lt;/li&gt;
&lt;li&gt;I’m willing to bet that the implementations of &lt;code&gt;validate*Header(headers)&lt;/code&gt; will have more and more duplication over time among them and that those implementations likely don’t actually care about checking HTTP request headers, but rather only the values they extract from those headers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don’t think any of these signals rises to the level of “Fix me now!”, but &lt;a href=&quot;https://www.jbrains.ca/sessions/whats-not-to-like-about-this-code&quot;&gt;I find it helpful to articulate the signals before I reply to them&lt;/a&gt;. This guides me to slow down, think a bit more, and judge the urgency of the situation more clearly. For the purposes of this article, we’ll refactor it anyway, setting aside the question of whether I would refactor it in an industrial-strength situations. It depends on the context and I’m not there right now.&lt;/p&gt;
&lt;h1 id=&quot;the-tests-as-we-first-encounter-them&quot;&gt;The Tests, As We First Encounter Them&lt;/h1&gt;
&lt;p&gt;Now let’s consider a typical programmer who wants to write tests for this code.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; They choose to use test doubles (“mock objects”) for this job, and they already know to &lt;strong&gt;stub queries&lt;/strong&gt;, so they use stubs (not expectations/mocks) in place of the production implementation of &lt;code&gt;HttpHeaders&lt;/code&gt;.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;aside&gt;
What’s that? &lt;a href=&quot;http://jmock.org/oopsla2004.pdf&quot;&gt;“Don’t mock types you don’t own”&lt;/a&gt;? Yes, that provides a shortcut to the same destination, which means that even if you don’t know this principle, you could (re)discover it for yourself!
&lt;/aside&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@ExtendWith(MockitoExtension.class)
class SignatureValidatorTest {
    ...
    @Mock
    private HttpHeaders headers;
    private MultivaluedMap&amp;lt;String, String&amp;gt; requestHeaders;

    @BeforeEach
    void setUp() {
        headers = mock(HttpHeaders.class);

        when(headers.getHeaderString(&amp;quot;Signature&amp;quot;))
            .thenReturn(SIGNATURE_HEADER);
        when(headers.getHeaderString(&amp;quot;Digest&amp;quot;))
            .thenReturn(DIGEST_HEADER);
        when(headers.getHeaderString(HttpHeaders.CONTENT_TYPE))
            .thenReturn(APPLICATION_JSON);

        requestHeaders = new MultivaluedHashMap&amp;lt;&amp;gt;();
        requestHeaders.add(&amp;quot;Signature&amp;quot;, SIGNATURE_HEADER);
        requestHeaders.add(&amp;quot;Digest&amp;quot;, DIGEST_HEADER);
        requestHeaders.add(&amp;quot;Content-Type&amp;quot;, APPLICATION_JSON);

        when(headers.getRequestHeaders())
            .thenReturn(requestHeaders);
    }

    // 10 tests that achieve great coverage below this line
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we focus on the test setup, which already shows some remarkable duplication: stubbing the same values two different ways with two different types! This happens often when we stub an interface that helpfully provides two views of the same data, such as &lt;code&gt;HttpServletRequest&lt;/code&gt; does with &lt;code&gt;getParameter(name)&lt;/code&gt; and &lt;code&gt;getParameterMap()&lt;/code&gt;. This tends to lead to a Morton’s Fork:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;stub both views of the data, whether we need them or not, for flexiblity’s sake, but creating Excessive Test Setup, a special kind of Irrelevant Details in Tests.&lt;/li&gt;
&lt;li&gt;stub only one view of the data, because it’s the only one we’re using, coupling the tests to implementation details that are likely to change, which impedes future refactoring.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When both options feel wrong, I invoke &lt;a href=&quot;https://www.imdb.com/title/tt0086567&quot;&gt;the wisdom of Joshua&lt;/a&gt;: the only winning move is not to play.&lt;/p&gt;
&lt;p&gt;In his article, Lars describes one approach: introduce a Narrowing Interface which removes redundancy and simplifies the interaction between a Request Handler and the Supplier of HTTP Headers. I would like to describe another approach that helps: &lt;a href=&quot;https://www.imdb.com/title/tt0087538&quot;&gt;blocking the kick by not being there&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-exactly-is-the-challenge-here&quot;&gt;What Exactly Is the Challenge Here?&lt;/h2&gt;
&lt;p&gt;Some of you can’t shake the feeling that this refactoring is an over-reaction. If you’re one of those people, then try writing those tests, even if you merely sketch them on paper. When I do this, I notice the following annoying pattern: I have to stub a bunch of functions I don’t care about to return values that I happen to know will pass “validation” (in the “are the HTTP Headers valid sense?”, not in the “is this signature valid?” sense—confusing!) in order to trick the code into constructing the value I actually want to use to test the &lt;code&gt;validate*Header()&lt;/code&gt; functions. &lt;strong&gt;All the tests that check the &lt;code&gt;else&lt;/code&gt; block want to assume that the &lt;code&gt;HttpHeaders&lt;/code&gt; value represents a valid request, but they are forced to depend on the details of determining whether those headers are valid, which makes the tests vulnerable to changes in behavior they don’t want to check.&lt;/strong&gt; Looking at this example, it’s not really a problem… until one day it very suddenly is.&lt;/p&gt;
&lt;h1 id=&quot;remove-duplication&quot;&gt;Remove Duplication&lt;/h1&gt;
&lt;p&gt;How do we remove duplication in the test setup? Fortunately, the test setup reveals the answer itself: collect all the stubs into a single Whole Value and extract a function that takes that Whole Value as its parameter.&lt;/p&gt;
&lt;p&gt;If we merely stubbed &lt;code&gt;headers.getRequestHeaders()&lt;/code&gt;, then we would be choosing one of the terrible options I outlined earlier: coupling the tests to the implementation choices of the production code. That suggests taking one more step: instead of depending on the function that supplies “Request Headers as a Dictionary”, let’s instead depend on a function that &lt;em&gt;demands&lt;/em&gt; “Request Headers as a Dictionary”.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;// Library/framework types that we can&amp;#39;t refactor
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;

class SignatureValidator {
    // Other details intentionally left out
    
    public void validateSignature(HttpHeaders headers) {
        if (headers.getHeaderString(DIGEST) == null 
           || headers.getHeaderString(SIGNATURE) == null) {
            ...
        } else {
            // How many times are we going to type &amp;quot;request headers&amp;quot;?!
            validateSignatureHeaderValues(
                getLowerCaseRequestHeaders(
                    headers.getRequestHeaders()));
        }
    }

    // Visible for testing, which means eventually extracted to its own class.
    public void validateSignatureHeaderValues(Map&amp;lt;String, String&amp;gt; signatureValidationRequest) {
        validateDigestHeader(signatureValidationRequest);
        validateSignatureHeader(signatureValidationRequest);
    }
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t love the new names, but I need to distinguish somehow between “validate signature” and “validate signature”.&lt;/p&gt;
&lt;h1 id=&quot;remove-duplication-again&quot;&gt;Remove Duplication Again&lt;/h1&gt;
&lt;p&gt;The duplication between the various meanings of “validate signature” reflects a pattern that I see very often in code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Python-like syntax for no reason other than it&amp;#39;s fun
doTheThing(valueTypeImposedByAnnoyingFramework):
    if (isValidAccordingToSomeRules(valueTypeImposedByAnnoyingFramework)):
        actuallyDoTheThingNow(valueTypeImposedByAnnoyingFramework)
    else:
        handleInvalidDataFromAnnoyingFramework()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first “do the thing” feels like optimism, but the second “do the thing” is really, absolutely, definitely do the thing now, because we’re super-duper sure that it’s now safe to do the thing. So do the thing. Now.&lt;/p&gt;
&lt;aside&gt;
Quite often, in code bases, we start with a single “do the thing”, but then we need to add some kind of input data validation when it comes time to expose &lt;code&gt;doTheThing()&lt;/code&gt; to the Horrible Outside World—as an HTTP service endpoint, for example. We have the impulse to call the request handler &lt;code&gt;doTheThing()&lt;/code&gt;, because it also does the thing. This creates confusion between “do the thing” (unless the HTTP request isn’t right) and “do the thing” (for real, for real this time).
&lt;/aside&gt;
&lt;p&gt;When I see this copied and pasted throughout an application, I feel confident about two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The corresponding tests are riddled with duplication, making them annoying to read.&lt;/li&gt;
&lt;li&gt;I can look like a wizard by simply extracting a Controller layer. (Branding. You know how it goes.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hardest-to-read tests are usually the ones that want to focus on “actually do the thing now” and ignore “is valid according to some rules” by &lt;strong&gt;assuming that the input is always valid, no matter what those rules are&lt;/strong&gt;.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; Some folks will extract the method &lt;code&gt;isValidAccordingToSomeRules()&lt;/code&gt;, move it onto an interface, then stub it to return &lt;code&gt;true&lt;/code&gt; in all the tests. This helps clarify the intention of the test, but it points directly to one more helpful pattern described in Alexis King’s now-classic essay, &lt;a href=&quot;https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/&quot;&gt;“Parse, Don’t Validate”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please don’t panic about the Haskell code samples; I don’t quite understand them myself. Even so, I can summarize a key point from that article—&lt;em&gt;deep breath&lt;/em&gt;: &lt;strong&gt;Instead of validating input, then passing valid values on the rest of the system directly, mark the value as “valid” somehow, so that future clients will not feel as though they need to check it again for validity, especially since they have absolutely no intention of defending themselves against invalid values, because they expect someone to have already done that by the time the data reaches them.&lt;/strong&gt; That’s what I understanding by &lt;em&gt;parsing&lt;/em&gt; instead of &lt;em&gt;validating&lt;/em&gt;: when we parse the &lt;code&gt;HttpHeaders&lt;/code&gt; value, we decide (once and for all) whether it is (syntactically) valid or not, then transform it into a Whole Value Type that’s convenient for the rest of the system—one that clearly represents parsing failure or another that clearly represents parsing success. From that point forward, &lt;strong&gt;there is no confusion about whether to trust the value we have in our hands&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This might sound like a complicated design choice, but it simplifies things quite significantly and pleasantly.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;// Library/framework types that we can&amp;#39;t refactor
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;

class SignatureValidator {
    // Other details intentionally left out

    // This pattern looks like it could be extracted to a library function.
    public void validateSignature(HttpHeaders headers) {
        try {
            handleValidateSignatureRequest(
                ValidateSignatureRequest.parseHttpHeaders(headers)
            );
        }
        catch (HttpHeadersParsingException handled) {
            ...
        }
    }

    public static class ValidateSignatureRequest {
        public static ValidateSignatureRequest parseHttpHeaders(
            HttpHeaders headers) {
            
            if (headers.getHeaderString(DIGEST) == null 
               || headers.getHeaderString(SIGNATURE) == null) {
                throw new ParsingException(...helpful details...);
            } else {
                return new ValidateSignatureRequest(...header values...);
            }
        }
        ...
    }

    // Renamed, because now we can more-easily distinguish it from the
    // framework request handler method.
    // 
    // Look at that! It can move into class ValidateSignatureRequest now!
    public void handleValidateSignatureRequest(
        ValidateSignatureRequest validateSignatureRequest) {
        
        validateDigestHeader(validateSignatureRequest);
        validateSignatureHeader(validateSignatureRequest);
    }
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s imagine the tests for these functions…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ValidateSignatureRequest.parseHttpHeaders()&lt;/code&gt;: maybe we stub &lt;code&gt;HttpHeaders&lt;/code&gt; and maybe we write integrated tests that talk to an HTTP server running in embedded mode in memory. Either way, we reduce the number of tests that duplicate irrelevant details. All the HTTP nonsense happens here.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;catch&lt;/code&gt; block: we can extract a function that takes the exception value as a parameter and decides how to signal the error back to the framework. It’s very likely that this code has very little to do with our Domain and everything to do with Annoying Framework. It almost certainly becomes reusable and part of a &lt;a href=&quot;https://www.refactoring.com/catalog/introduceLocalExtension.html&quot;&gt;Local Extension&lt;/a&gt; to Annoying Framework. There might even be a library function or two in Annoying Framework that already does what we want! All the Annoying Framework nonsense happens here.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handleValidateSignatureRequest()&lt;/code&gt; now knows nothing at all about HTTP nor Annoying Framework, which makes it significantly less annoying to test. It can also safely assume that any &lt;code&gt;ValidateSignatureRequest&lt;/code&gt; value is syntactically valid, because its constructors can stop you from creating invalid values.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the three kinds of behavior are tangled together, it’s easy to become too tired to write thorough tests for each part. When I encounter code bases like this, &lt;strong&gt;I routinely find at least one missing test that the local programmers agree that they wish they’d written&lt;/strong&gt;. When we untangle those behaviors, that drastically increases the chances that the programmers will choose to write all the tests they believe they need. (Even if they “get that wrong”, I feel much more satisfied when they’ve made a conscious choice, rather than been driven by frustration and exhaustion to cut corners.)&lt;/p&gt;
&lt;h2 id=&quot;dont-we-need-to-test-the-request-handler&quot;&gt;Don’t We Need To Test the Request Handler?&lt;/h2&gt;
&lt;p&gt;Well… test wherever you need more confidence!&lt;/p&gt;
&lt;p&gt;If you wrote thorough tests for &lt;code&gt;SignatureValidator.validateSignature(HttpHeaders headers)&lt;/code&gt;, then you’d notice yourself writing very similar tests for the next Controller. And the next Controller. And the next Controller. Eventually, you’d decide that as long as you followed the pattern and tested all the Steps of the “standard Workflow”, then you wouldn’t need to test the Workflow any more. That works for me!&lt;/p&gt;
&lt;p&gt;You could even extract the Workflow to its own function and test it thoroughly, if you liked.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;import javax.ws.rs.core.HttpHeaders;

class StandardControllerWorkflow&amp;lt;ApplicationRequestType&amp;gt; {
    private final ParseHttpHeaders parseHttpHeaders;
    private final Consumer&amp;lt;ApplicationRequestType&amp;gt; requestProcessor;
    private final Consumer&amp;lt;HttpHeadersParsingException&amp;gt; invalidRequestHandler;

    public void acceptHttpHeaders(HttpHeaders headers) {
        try {
            requestProcessor.accept(
                parseHttpHeaders.parse(headers)
            );
        }
        catch (HttpHeadersParsingException handled) {
            invalidRequestHandler.accept(handled);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you use this to create Controllers in Annoying Framework, the resulting code seems Too Simple to Break, especially if you already trust the Workflow.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;class SignatureValidator {
    private final StandardControllerWorkflow&amp;lt;ValidateSignatureRequest&amp;gt; workflow
        = new StandardControllerWorkflow&amp;lt;ValidateSignatureRequest&amp;gt;(...);

    // This pattern looks like it could be extracted to a library function.
    public void validateSignature(HttpHeaders headers) {
        workflow.acceptHttpHeaders(headers);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could go even further, replacing this compile-time class with an Abstract Factory, but that’s a digression for the purposes of this article. I wouldn’t &lt;em&gt;rush&lt;/em&gt; to do it, but I could seem myself eventually doing it.&lt;/p&gt;
&lt;h1 id=&quot;simpler-but-not-easier-except-also-easier&quot;&gt;Simpler, But Not Easier, Except Also Easier&lt;/h1&gt;
&lt;p&gt;This design exemplifies the distinctions between “simple” and “easy”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;simpler: has fewer moving parts, can be understood by knowing fewer things&lt;/li&gt;
&lt;li&gt;easier: requires less effort to produce&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This design seems to me to make the production code simpler, but not easier while making the tests both simpler and easier. Notably, the “process valid request” tests no longer need to even &lt;em&gt;think&lt;/em&gt; about invalid request values, whereas the “check the HTTP Headers” tests no longer need to even &lt;em&gt;think&lt;/em&gt; about how the Controller might want to process a valid request. &lt;strong&gt;This isolation makes those easier to write, so we’re more likely write them all, and even more importantly, simpler to understand, so we’re less likely to doubt them when we encounter them again in six months, trying to fix a defect&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Here I describe a pattern for simplifying the Controller layer in a typical application using a typical Application Framework. This pattern results in more-focused tests with fewer unpleasant surprises, more opportunities for reuse, easier-to-grasp Domain Behavior, and just happens to reduce the reliance on test doubles. Between this pattern and the one that Lars Eckart describes in his article, you now have two ways to improve the design of this part of your applications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hide Annoying Framework details behind a Narrower Interface That You Control.&lt;/li&gt;
&lt;li&gt;Avoid Annoying Framework details entirely by decoupling from them more aggressively.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which should you choose? I don’t know. You decide. You can imagine the first one as an intermediate step towards the second one. You can imagine the first one as a compromise when someone labels the second one as “overengineering”.&lt;/p&gt;
&lt;p&gt;Do what makes you happy.&lt;/p&gt;
&lt;p&gt;You can choose.&lt;/p&gt;
&lt;h1 id=&quot;epilog&quot;&gt;Epilog&lt;/h1&gt;
&lt;p&gt;Functional Programming design gives us another interesting step to consider: Replace Custom Code with Library Functions. This example is a &lt;em&gt;purely mechanical refactoring&lt;/em&gt;, a phrase I use to describe refactorings that you can perform safely even when you don’t understand the intention of the code. The specific refactoring in question is &lt;strong&gt;Replace Exception with Either&lt;/strong&gt;. If you don’t know about the Either type, then you can safely ignore this epilogue &lt;em&gt;or&lt;/em&gt; use it as a chance to become acquainted with the type. If you know the Either type, then you might know that &lt;a href=&quot;https://vavr.io&quot;&gt;Vavr&lt;/a&gt; has become a standard third-party library for Java programmers interested in FP design and provides the Either type.. This means that we have the option of performing this refactoring in Java with Vavr.&lt;/p&gt;
&lt;p&gt;We could replace this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;// Both paths return values of the same type.
try {
    return happyPath.accept(parser.parse(...input...));
}
catch (Exception handled) {
    return recoveryStrategy.accept(handled);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;with this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;return parser.parse(...input...)
    .fold(
        parsingFailure -&amp;gt; recoveryStrategy.accept(parsingFailure),
        parsedValue -&amp;gt; happyPath.accept(parsedValue)
    );&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;by changing &lt;code&gt;parse()&lt;/code&gt; to return &lt;code&gt;Either&amp;lt;Exception, ParsedValue&amp;gt;&lt;/code&gt; instead of maybe returning &lt;code&gt;ParsedValue&lt;/code&gt; and maybe throwing &lt;code&gt;Exception&lt;/code&gt;. And nothing requires the “failure” value type of an &lt;code&gt;Either&lt;/code&gt; to be an &lt;code&gt;Exception&lt;/code&gt;: it can be any type you like. I tend to prefer to use simple Whole Value types or records to represent failure values.&lt;/p&gt;
&lt;p&gt;Now, I think, it becomes even clearer that this is a standard pattern that we can trust: it’s literally a library function, albeit one with the quirky name &lt;code&gt;fold()&lt;/code&gt;. (I think of &lt;code&gt;fold()&lt;/code&gt; as “take a bunch of values and fold them into a single value”. You might know it as &lt;code&gt;reduce()&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;And if you prefer, you could use Java’s lambda expression syntax to make the code even more concise and easier to skim:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;return parser.parse(...input...).fold(
    recoveryStrategy::accept,
    happyPath::accept
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’re familiar with this syntax, then you might prefer to read this, but if you’re not familiar with it, then it might look alien. You decide which version you prefer and which version better meets the needs of your project community.&lt;/p&gt;
&lt;p&gt;In our case, unfortunately, Annoying Framework’s request handlers return nothing (&lt;code&gt;void&lt;/code&gt;) instead of something. This means that Annoying Framework actively resists Vavr, whose library functions generally prefer to work with higher-order functions that return a value, rather than quietly consume their input. You could still use Vavr for this purpose, but you might not like the results. You’ll only find out if you try!&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I will add a link once Lars publishes his article and I have a link to add.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;For this article I have set aside whether this would or wouldn’t have happened if the programmers had practised TDD. I know that I have written tests that look this like while practising TDD. I wouldn’t do that nowadays, but that’s precisely because I know the refactoring that this article is here to describe!&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;For this article I have ignored the reasons why the programmer chose to use test doubles for this purpose. That’s not what this article is about. Things are the way they are because they got that way.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;That’s one of the points of &lt;em&gt;abstraction&lt;/em&gt;: to be able to depend on the result without having to know or care about how the result was calculated.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Tue, 18 Jul 2023 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/from-stubs-to-parsers</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/from-stubs-to-parsers</guid>
        
        
        <category>Simple Design</category>
        
        <category>Mock Objects</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>The Power of Precise Names: An Example</title>
        <description>&lt;p&gt;A member of &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;The jbrains Experience&lt;/a&gt; posted about a name they had just encountered in their day-job code base:&lt;/p&gt;
&lt;aside&gt;
&lt;code&gt;compareReportedProfileToTargetProfileAndReportResultToSupervisor()&lt;/code&gt;
&lt;/aside&gt;
&lt;p&gt;They reported that they’d already renamed the method, but I immediately saw it as an example of how naming fits together with refactoring. I wanted to combine a version of playing &lt;a href=&quot;https://www.jbrains.ca/sessions/whats-not-to-like-about-this-code&quot;&gt;“What’s Not To Like About This Code?”&lt;/a&gt; with imagining how we might “fix” this method.&lt;/p&gt;
&lt;aside&gt;
I’d like to note before we start that &lt;strong&gt;I don’t know the context of this method, this code base, nor the group working in it&lt;/strong&gt;, so I couldn’t possibly &lt;em&gt;recommend&lt;/em&gt; specific refactorings in this case. Instead, I intend only to explore what this name—all on its own—suggests to me.
&lt;/aside&gt;
&lt;h1 id=&quot;whats-to-like-about-this-name&quot;&gt;What’s To Like About This Name?&lt;/h1&gt;
&lt;p&gt;I really like this name, because &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names&quot;&gt;I find it &lt;strong&gt;precise&lt;/strong&gt;&lt;/a&gt;. (I can’t judge whether it is &lt;strong&gt;accurate&lt;/strong&gt;, so I have to hope that it is. Let me hope.) A precise name might overstate implementation details, but at least &lt;strong&gt;it usually costs less to summarize implementation details than it costs to reverse-engineer them from a vague name&lt;/strong&gt;. Accordingly, although some might roll their eyes at this name for being “typical Java”, I find its precision quite helpful.&lt;/p&gt;
&lt;h2 id=&quot;and-or-then&quot;&gt;“And” or “Then”?&lt;/h2&gt;
&lt;p&gt;I immediately notice the word “and” have the impulse to change it to “then”. I freely admit that this comes from, of all places, &lt;a href=&quot;https://www.youtube.com/watch?v=Jtq1EBMe1gQ&amp;amp;t=108s&quot;&gt;the sitcom Frasier&lt;/a&gt;. In the episode, pedantic Frasier and Niles annoy their teacher by distinguishing carefully between “twist, then pull” (do the twisting, then afterward do the pulling) and “twist and pull” (maybe twist and pull at the same time). Although this kind of pedantry typically indicates occupying a &lt;a href=&quot;http://www.satirworkshops.com/files/Stances.pdf&quot;&gt;Blaming Stance&lt;/a&gt;, I find it helpful when examining the names of things &lt;strong&gt;in a code base, where precision is not only welcome but needed&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does sequence matter here?&lt;/strong&gt; I don’t know, but my experience tells me to err on the side of assuming that we must preserve the sequence of statements we find in unfamiliar code. This leads me to replace “and” with “then”, then look for signs that “then” doesn’t “sound right”. You could think of this as the guideline &lt;strong&gt;Assume “then”, then hope for “and”&lt;/strong&gt;. If the sequence of statements doesn’t matter, then we can freely reorder them without breaking the system, and that increases our options for refactoring. It also makes the code simpler by eliminating a detail that we’d otherwise need to know. Accordingly, I would rename this method by changing “and” to “then” until someone could state with confidence that the sequence of events is a free choice.&lt;/p&gt;
&lt;p&gt;In this case, “compute X then report X to Y” seems very clear to me: we can’t report X to Y until we’ve computed X.&lt;/p&gt;
&lt;h2 id=&quot;the-magic-of-then&quot;&gt;The Magic of “Then”&lt;/h2&gt;
&lt;p&gt;Once I introduce “then” into a function name, that suggests an obvious next step to me: &lt;strong&gt;splitting the function into two composable parts&lt;/strong&gt;. Very often, I find each part easier to understand and test on its own. Almost always, I find that once I trust each part, &lt;strong&gt;I don’t need to test the composition&lt;/strong&gt;, because there is only one way to compose the parts, &lt;a href=&quot;https://junit.org/junit4/faq.html#best_3&quot;&gt;it’s clear, and it’s obvious&lt;/a&gt;. In The Old Days, we talked about some code as “Too Simple to Break” as a way to decide how much testing was too much or just enough. I offer this guideline:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If I trust &lt;code&gt;f()&lt;/code&gt; and I trust &lt;code&gt;g()&lt;/code&gt;, and there’s only one way to compose &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; that way is clear and obvious, then &lt;code&gt;compose(f, g)&lt;/code&gt; is almost certainly Too Simple to Break.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I would like to emphasize one point: composing &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; will not break, but that doesn’t mean that the composition does what you need. You might still need to check that the composition solves the business problem that you care about, but at least you’d feel comfortable and confident stating that whatever it does, it does &lt;em&gt;correctly&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Returning to the example, I would expect to split this method into two parts: &lt;code&gt;compareReportedProfileToTargetProfile()&lt;/code&gt; and &lt;code&gt;reportProfileComparisonResultToSupervisor()&lt;/code&gt;. You’ll notice that in the process of removing the second part from its context, I chose to add back some details in order to &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;increase clarity&lt;/a&gt;. I did this &lt;strong&gt;now, while the relevant details are fresh in my working memory&lt;/strong&gt;, rather than relying on someone to rediscover these details later and &lt;strong&gt;under pressure&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Next, I’d like to make the composition of these new functions clear and obvious. I imagine the code would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def compareReportedProfileToTargetProfileThenReportResultToSupervisor() {
    reportProfileComparisonResultToSupervisor(
        compareReportedProfileToTargetProfile()
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even better, given my recent (but limited!) experience with languages such as PureScript, I imagine the code more like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compareReportedProfileToTargetProfileThenReportResultToSupervisor =
    compareReportedProfileToTargetProfile |&amp;gt; reportProfileComparisonResultToSupervisor&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function &lt;code&gt;|&amp;gt;&lt;/code&gt; composes functions in a way that lets us read it the composition as “then” instead of the traditional “follows”. This is a way to compose functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; when the output from &lt;code&gt;f&lt;/code&gt; naturally becomes the input to &lt;code&gt;g&lt;/code&gt;. In this situation, there is only one clear and obvious way to compose these functions. If we have any build-time type checking, then I would feel completely confident composing these functions without testing the composition.&lt;/p&gt;
&lt;p&gt;This means, incidentally, that I expect &lt;code&gt;compareReportedProfileToTargetProfile()&lt;/code&gt; to return some kind of Profile Comparison value and &lt;code&gt;reportProfileComparisonResultToSupervisor()&lt;/code&gt; to need a Profile Comparison value as an argument. Here, the desirable structure of the composition matches the emerging names, which gives me a warm, fuzzy feeling that I’m on a good track.&lt;/p&gt;
&lt;h2 id=&quot;not-pulling-its-weight&quot;&gt;Not Pulling Its Weight&lt;/h2&gt;
&lt;p&gt;Next, I notice that the composition of these two functions doesn’t seem to be pulling its weight, so I have the impulse to inline &lt;code&gt;compareReportedProfileToTargetProfileThenReportResultToSupervisor()&lt;/code&gt;. I wouldn’t do it yet, because it provides a Warm, Dry Place to keep refactoring the pieces, but I would expect to inline this Workflow function as part of Cleaning Up Before Moving On.&lt;/p&gt;
&lt;h2 id=&quot;less-code-fewer-distractions&quot;&gt;Less Code, Fewer Distractions&lt;/h2&gt;
&lt;p&gt;Now that I’ve split the original function into two composable parts, I can focus on each part independently without feeling distracted by how to put them together. Putting them together has become clear and obvious. This eliminates potential distractions, helps me focus (narrow my attention), decreases the cost of noticing things, and thereby increases the likelihood that I’ll notice things.&lt;/p&gt;
&lt;h2 id=&quot;context-dependent-code&quot;&gt;Context-Dependent Code&lt;/h2&gt;
&lt;p&gt;The name &lt;code&gt;compareReportedProfileToTargetProfile()&lt;/code&gt; bothers me because it seems to overstate its context. My intuition is screaming at me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Surely we don’t need to know that it’s a &lt;em&gt;reported&lt;/em&gt; profile and a &lt;em&gt;target&lt;/em&gt; profile that we’re comparing! Comparing profiles is comparing profiles, isn’t it?!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I certainly hope so. Now I feel the impulse to rename this function to &lt;code&gt;compareProfiles(a, b)&lt;/code&gt;. This removes the function from its context, making it &lt;a href=&quot;/permalink/how-reuse-happens&quot;&gt;less expensive to use in new contexts&lt;/a&gt;, which makes reuse more likely to happen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wait… won’t we lose the context?&lt;/strong&gt; No. When we rename &lt;code&gt;compareReportedProfileToTargetProfile()&lt;/code&gt; to &lt;code&gt;compareProfiles()&lt;/code&gt;, the context will remain in the hands of the client, where it belongs. The names of the arguments will carry the context from now on.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compareReportedProfileToTargetProfileThenReportResultToSupervisor =
    compareProfiles reportedProfile targetProfile
        |&amp;gt; reportProfileComparisonResultToSupervisor&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we were writing this the Object-Oriented Way, then it would look more like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def compareReportedProfileToTargetProfileThenReportResultToSupervisor() {
    reportProfileComparisonResultToSupervisor(
        reportedProfile.compareTo(targetProfile)
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;a-slight-detour&quot;&gt;A Slight Detour&lt;/h3&gt;
&lt;p&gt;The method name &lt;code&gt;compareTo()&lt;/code&gt; probably fits into some &lt;code&gt;Comparable&lt;/code&gt; framework so that generic algorithms can compare abstractly-comparable things. I don’t know yet what a &lt;code&gt;Profile&lt;/code&gt; is, but I know it’s &lt;code&gt;Comparable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;Comparable&lt;/code&gt; frameworks tend to reduce comparison to only “less than, equal to, or greater than”, that might not suffice for our design. We might need a richer &lt;code&gt;ProfileComparison&lt;/code&gt; value. In that case, I’d choose a different name to highlight that I’m not trying to fit &lt;code&gt;Profile&lt;/code&gt; objects into the &lt;code&gt;Comparable&lt;/code&gt; framework. That would leave us with a function such as this one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def compareProfiles(first, second) {
    # I don&amp;#39;t know how to compare profiles, but I&amp;#39;m sure it&amp;#39;s interesting.
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or, if we have type declarations to guide us:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compare :: Profile -&amp;gt; Profile -&amp;gt; ProfileComparison
compare aProfile anotherProfile = ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ooh! This could eventually turn into a generic comparison type…&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compare :: forall a. a -&amp;gt; a -&amp;gt; Comparison a&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…but I’m getting ahead of myself. &lt;strong&gt;I don’t mind thinking ahead, but I prefer not to design ahead&lt;/strong&gt;. This last step starts to move in the direction of the &lt;code&gt;Comparable&lt;/code&gt; framework and we’re not going there now. &lt;a href=&quot;https://martinfowler.com/bliki/Yagni.html&quot;&gt;Maybe later, maybe never&lt;/a&gt;. &lt;strong&gt;Once I see where I might go, I don’t need to go there now&lt;/strong&gt;. Instead, I can consider it as part of Cleaning Up Before Moving On.&lt;/p&gt;
&lt;h3 id=&quot;where-were-we&quot;&gt;Where Were We?&lt;/h3&gt;
&lt;p&gt;Ah, yes. We had removed the context from &lt;code&gt;compareReportedProfileToTargetProfile()&lt;/code&gt;, turning it into the simpler &lt;code&gt;compareProfiles()&lt;/code&gt;, or even simply &lt;code&gt;compare(Profile first, Profile second)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;report-x-to-y&quot;&gt;“Report X to Y”&lt;/h2&gt;
&lt;p&gt;The phrase “report X to Y” sounds very strange to me when I see it in a codebase. Isn’t that… just… applying a function?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def reportProfileComparisonResultToSupervisor(profileComparison, supervisor) {
    supervisor.doSomethingExcellentWith(profileComparison)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function clearly doesn’t pull its weight, so I’d inline it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reportProfileComparisonResultToSupervisor profileComparison supervisor =
    doSomethingExcellentWith supervisor profileComparison&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This version of the function makes it even more clear: &lt;code&gt;reportProfileComparisonResultToSupervisor()&lt;/code&gt; acts as merely an alias for &lt;code&gt;doSomethingExcellentWith()&lt;/code&gt;, so I’d inline it.&lt;/p&gt;
&lt;p&gt;Unfortunately, sometimes the programmer doesn’t see it this clearly, so they end up with indirection without abstraction.&lt;/p&gt;
&lt;h3 id=&quot;what-often-happens&quot;&gt;What Often Happens&lt;/h3&gt;
&lt;p&gt;Let us return to this form of the code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def compareReportedProfileToTargetProfileThenReportResultToSupervisor() {
    reportProfileComparisonResultToSupervisor(
        reportedProfile.compareTo(targetProfile)
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, let us introduce the necessary details:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Supervisor is a concrete type or a class.
def compareReportedProfileToTargetProfileThenReportResultToSupervisor(
    reportedProfile, targetProfile, Supervisor supervisor) {

    reportProfileComparisonResultToSupervisor(
        supervisor,
        reportedProfile.compareTo(targetProfile),
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to test this, many programmers start reasonably enough by introducing an abstract supervisor so that they can “mock” (set expectations on) the supervisor and detect whether it was invoked correctly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# I don&amp;#39;t recommend naming interfaces starting with &amp;quot;I&amp;quot;, but I&amp;#39;m doing it
# here to emphasize that ISupervisor is an interface/abstraction.
def compareReportedProfileToTargetProfileThenReportResultToSupervisor(
    reportedProfile, targetProfile, ISupervisor supervisor) {

    supervisor.accept(
        reportedProfile.compareTo(targetProfile),
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks fine, but the resulting tests become quite annoying:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I need to create two &lt;code&gt;Profile&lt;/code&gt; that happen to compare to the &lt;code&gt;ProfileComparison&lt;/code&gt; value that I care about.&lt;/li&gt;
&lt;li&gt;I need to expect that &lt;code&gt;supervisor.accept()&lt;/code&gt; is called with that &lt;code&gt;ProfileComparison&lt;/code&gt; value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I had 12 different &lt;code&gt;ProfileComparison&lt;/code&gt; values, I’d be copying and pasting &lt;em&gt;a lot&lt;/em&gt; of irrelevant details from test to test. &lt;strong&gt;And what exactly would I be testing here?&lt;/strong&gt; I’d be using the expectations on &lt;code&gt;supervisor.accept()&lt;/code&gt; as an indirect way to check the result of &lt;code&gt;compareTo()&lt;/code&gt;. I’d be testing &lt;code&gt;compareTo()&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;But… I could test it much more directly by simply invoking it and checking the result with &lt;code&gt;assertEquals()&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;This provides a textbook example of unhelpful indirection.&lt;/p&gt;
&lt;h3 id=&quot;remove-the-unhelpful-intermediary&quot;&gt;Remove the Unhelpful Intermediary&lt;/h3&gt;
&lt;p&gt;I see this pattern often in code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def workflow(a, b, c, target) {
    target.doSomethingWith(
        computeSomethingFrom(a, b, c)
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It seems perfectly reasonable, but it creates the exact testing headaches that I mentioned a moment ago. I find the design much simpler if I merely inline &lt;code&gt;workflow()&lt;/code&gt; and treat the composition as “Too Simple to Break”. The alternative is to extract an interface for &lt;code&gt;target&lt;/code&gt;, but then &lt;code&gt;Target.accept()&lt;/code&gt; becomes nothing more than an alias of “apply function” that can only apply functions to &lt;code&gt;Target&lt;/code&gt; objects. You can see this with one simple refactoring: push &lt;code&gt;computeSomethingFrom(a, b, c)&lt;/code&gt; up the call stack and you get:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def workflow(result, target) {
    target.doSomethingWith(result)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope we can all agree that &lt;code&gt;workflow()&lt;/code&gt; is now nothing more than an alias for &lt;code&gt;doSomethingWith()&lt;/code&gt;. Inline it! This is a textbook example of &lt;strong&gt;unhelpful indirection&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-final-result&quot;&gt;The Final Result&lt;/h2&gt;
&lt;p&gt;We end up with code that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compareProfiles reportedProfile targetProfile
    |&amp;gt; doSomethingImportantWithProfileComparison supervisor&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or, if you prefer the OO version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;supervisor.doSomethingImportantWithProfileComparison(
    reportedProfile.compareTo(targetProfile)
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maybe &lt;code&gt;Supervisor&lt;/code&gt; can behave like some generic &lt;code&gt;Consumer&amp;lt;ProfileComparison&amp;gt;&lt;/code&gt;… no. Not yet. Maybe later, maybe never. I like that I had the impulse, but I don’t need that now. &lt;strong&gt;I’m ready to do that, but not eager to do that&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When I see this result, I see two independent, easily-tested, easily-understood functions that I can compose in only one way that seems both clear and obvious, and therefore seems Too Simple to Break. That sounds like a win to me! &lt;strong&gt;And all this by looking at a single name!&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&quot;epilog-are-you-kidding-me&quot;&gt;Epilog: Are You &lt;em&gt;Kidding&lt;/em&gt; Me?!&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;J. B., you can’t be serious! All this overengineering because of a single name?! What’s &lt;em&gt;wrong&lt;/em&gt; with you?! This is why all you XP/TDD types seem like pointless thoughtleaders….&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I understand, believe me. Does it help if I mention that &lt;strong&gt;I had all these thoughts &lt;em&gt;and&lt;/em&gt; performed the corresponding the refactorings in about 30 seconds&lt;/strong&gt;? It seems interminable when we write about and read about it in gory detail, but it happens so quickly in the mind, especially for someone &lt;a href=&quot;https://blog.jbrains.ca/permalink/test-driven-development-as-pragmatic-deliberate-practice&quot;&gt;with non-trivial experience&lt;/a&gt;. You might need 10 minutes to do all this the first time, but before long, you’ll do it so effortlessly that you won’t even notice it.&lt;/p&gt;
</description>
        <pubDate>Fri, 28 Apr 2023 11:52:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/refactoring-by-focusing-on-names-example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/refactoring-by-focusing-on-names-example</guid>
        
        
        <category>Refactoring</category>
        
        <category>Improving Names</category>
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>How Tests Support Refactoring</title>
        <description>&lt;p&gt;I have witnessed programmers express annoyance about how tests seem to interfere with changing production code. A discussion on this topic &lt;a href=&quot;https://mastodon.social/@nat@ruby.social/109938741113806550&quot;&gt;led here&lt;/a&gt;:&lt;/p&gt;
&lt;iframe src=&quot;https://ruby.social/@nat/109938740857766771/embed&quot; class=&quot;mastodon-embed&quot; style=&quot;max-width: 100%; border: 0 none; padding: 1em&quot; allowfullscreen=&quot;allowfullscreen&quot; width=&quot;300&quot; height=&quot;600&quot;&gt;
&lt;/iframe&gt;
&lt;p&gt;In particular, it raised this commonly-heard expression of frustration in the vein of &lt;a href=&quot;https://blog.jbrains.ca/permalink/ask-why-but-never-answer&quot;&gt;“Ask Why, But Never Answer”&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Aren’t tests supposed to make refactoring easier???&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Isn’t that better? You can let go of this expectation now. May you be at peace.&lt;/p&gt;
&lt;p&gt;Tests make refactoring &lt;strong&gt;safer&lt;/strong&gt;, but not necessarily &lt;em&gt;easier&lt;/em&gt;. Sometimes, by accident, they do both.&lt;/p&gt;
&lt;p&gt;If you judge that the safety is no longer worth the investment, then you can safely throw the tests away. This carries the risk of committing early to “rolling forward” (or going back and trying again), but &lt;strong&gt;throwing away the tests is always safe&lt;/strong&gt; in the sense that doing this must never break production code.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; At worst, it makes changing that production code more expensive—a risk that you can manage in a variety of ways.&lt;/p&gt;
&lt;p&gt;But if you’re expecting tests to (generally) make refactoring &lt;em&gt;easier&lt;/em&gt;, then you’re expecting too much. Nothing can (generally) do that. You’ll have to settle for making refactoring less risky in other ways, less expensive overall, and ultimately less stress-inducing. Tests certainly help me do &lt;em&gt;that&lt;/em&gt;, at least on most days most of the time.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I use “must” here precisely and deliberately. Not “should”, but &lt;em&gt;must&lt;/em&gt;. If you break this rule, then you have more-urgent problems. Plz fix.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Tue, 28 Feb 2023 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-tests-support-refactoring</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-tests-support-refactoring</guid>
        
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>Investing Wisely in Architecture Through Refactoring</title>
        <description>&lt;p&gt;A member of my &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;mentoring group&lt;/a&gt; started a discussion regarding this article: &lt;a href=&quot;https://victorrentea.ro/blog/overengineering-in-onion-hexagonal-architectures/&quot;&gt;Victor Rentea’s “Overengineering in Onion/Hexagonal Architectures”&lt;/a&gt;. They commented that the article made them feel uncomfortable, because Victor’s advice seemed to be to drop all these architecture choices, because they represent overengineering. I wrote some words about this topic there and then I decided to refine my thinking and publish it here.&lt;/p&gt;
&lt;h1 id=&quot;the-short-version&quot;&gt;The Short Version&lt;/h1&gt;
&lt;p&gt;We tend to use guidelines about design and architecture as protection against under-investing in design. This choice tends naturally to lead to a certain amount of over-investing in design before finding a helpful balance. I believe these two things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;This is a natural part of learning (for most people most of the time&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;) and therefore not a problem to solve.&lt;/li&gt;
&lt;li&gt;Refactoring provides a clear path to investing wisely in design: not too much and not too little.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This explains why I don’t directly try to stop programmers from “over-engineering” by following one of these Concentric Architecture&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; schools, but instead teach them to engage these ideas with the mantra “don’t worry about where the code goes, but rather how the code flows”. The more confident they feel refactoring towards these dependency patterns, the more they can avoid over-investing up front in making every dependency “right” from their moment of birth.&lt;/p&gt;
&lt;p&gt;That’s as short as I could make it. I tried.&lt;/p&gt;
&lt;h1 id=&quot;a-less-short-version&quot;&gt;A Less-Short Version&lt;/h1&gt;
&lt;p&gt;Under-investing in design remains the norm on software projects. When programmers start to learn about investing in design, they rightly conclude that they need to invest &lt;em&gt;more&lt;/em&gt; in design, but they lack the judgment to invest &lt;em&gt;well&lt;/em&gt; in design, so they tend to invest &lt;em&gt;too much&lt;/em&gt; for a while. If they let themselves have the experience they need to refine their judgment, they’ll eventually start noticing that they’re over-investing in design, then try investing less until they find a helpful balance. I consider this a natural part of the learning process. I conjecture that &lt;strong&gt;it’s even a necessary part of the learning process&lt;/strong&gt;, although I have no real evidence for that claim beyond anecdotal observation.&lt;/p&gt;
&lt;p&gt;Programmers who broadly prefer a Lightweight approach to software practice tend to practise some form of evolutionary design, such as &lt;a href=&quot;https://tdd.training&quot;&gt;test-driven development&lt;/a&gt;. &lt;strong&gt;They learn to use refactoring as a way to manage the risks of over- and under-​investing in design&lt;/strong&gt;, because refactoring allows them to recover from both over- and under-​investment when they encounter it. Over time, they converge towards a balance that they consider “just-enough investment”, which I’m calling &lt;em&gt;investing wisely in design&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;All this explains why I practise the way I do and teach the way I do. I don’t try to push specific architecture patterns, but instead teach refactoring as &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;a general practice aimed at internalizing the tradeoffs of various design choices&lt;/a&gt;. I don’t want to short-circuit your learning by trying to upload “the right answers” into your mind; instead, I try to provide you with the &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest&quot;&gt;simplest rules I know that are aimed at helping you invest wisely in design&lt;/a&gt;. &lt;strong&gt;I don’t try to stop you from over-investing in design, because I recognize it as an important (even beneficial) stage of learning&lt;/strong&gt;; I encourage you to create a safe space where you can freely over-invest in design: by writing code test-first, by practising refactoring, and by surrounding yourself with advisors who can help you make sense of the consequences of your choices. Using this approach, programmers develop skill and judgment over time, rather than merely learn to follow a certain set of rules. Not only do they learn to invest more-wisely in design, but they also develop a skill that helps them navigate unfamiliar situations, including unfamiliar technology stacks, unfamiliar group dynamics, and unfamiliar (often dysfunctional) enterprises. They not only invest wisely in design but also learn to adjust their strategies to invest more wisely in more situations over time.&lt;/p&gt;
&lt;p&gt;I interpret Victor’s article as the outcome of a programmer allowing themself to go through this learning process. It describes one person’s conclusions regarding which kinds of over-investing to watch out for, based on which specific forces they’ve encountered (been hurt by!) along the way. Unfortunately, some readers will interpret his advice as rules that they ought to follow in order to learn from his mistakes. We writers run that risk every time we write an advice article. (I’m risking that right now!) &lt;strong&gt;Read context-free advice with extreme caution&lt;/strong&gt;. For example, where Victor suggests “collapse these layers”, I suggest “be prepared to collapse these layers”. This means at least two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learn how to collapse those layers so that you can do it when you need to. To do this, you’ll probably need to overdo it more than a few times.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dhemery.com/articles/resistance_as_a_resource/&quot;&gt;Understand your resistance (or someone else’s!)&lt;/a&gt; to collapsing those layers, so that you don’t lose the opportunity to do it when you need to. Remember that you are not your code, but you are (presumably) a human and humans don’t always react rationally to their environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The web is full of articles like this one, which provide helpful wisdom mixed up with advice to “always do this” and “never do that”. Even the writers that don’t directly write “always” and “never” typically know that their readers will tend to do what they suggest. Some of them even manipulate their audience by not outright telling them “always” and “never”, but expecting them to insert those words into their minds themselves. &lt;strong&gt;I teach refactoring ultimately as an antidote to all that&lt;/strong&gt;. A programmer who comfortably changes their design decisions avoids this fate. They don’t need to pick “the right set of rules” to follow, because they feel confident changing their mind and adjusting their strategies to fit the situation. They rarely feel paralyzed by a choice because they feel comfortable changing it later. They learn from others, rather than adhere to a school of thought. They experiment and adjust, rather than try in vain to predict the future. They—dare I even write it?—&lt;em&gt;embrace change&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;(Sorry. Once I felt myself moving in the direction of those words, I couldn’t resist.)&lt;/p&gt;
&lt;h1 id=&quot;a-few-gory-details&quot;&gt;A Few Gory Details&lt;/h1&gt;
&lt;p&gt;You can stop here, but if you’re interested in a few more details, you can find them below.&lt;/p&gt;
&lt;h2 id=&quot;i-dont-call-it-engineering-because-it-mostly-isnt&quot;&gt;I Don’t Call It “Engineering”, Because It Mostly Isn’t&lt;/h2&gt;
&lt;p&gt;First, you’ll notice that I shy away from the terms “over-engineering” and “under-engineering”. I do this for at least two reasons:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I consider what we programmers do as &lt;em&gt;craft&lt;/em&gt;, not &lt;em&gt;engineering&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;I prefer more transparent terms that more-directly express what we mean.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For this reason, at least as of early 2023, &lt;strong&gt;I prefer to talk about investing in design&lt;/strong&gt; where other people talk about the “level of engineering”. Notice that I also take the Martin Fowler view of architecture&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;, which means that I typically talk about &lt;em&gt;design&lt;/em&gt; instead of architecture and treat architecture decisions as design decisions with one additional, particular, strong constraint.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; When Victor writes “overengineering” and I write “over-investing in design”, I believe we mean the same thing. Close enough, anyway.&lt;/p&gt;
&lt;h2 id=&quot;under-investment-in-design-remains-very-common&quot;&gt;Under-Investment in Design Remains Very Common&lt;/h2&gt;
&lt;p&gt;I don’t have research findings to support this claim, so I would happily change my mind if presented with surveys that showed me otherwise. Most projects most of the time under-invest in their design. They create &lt;a href=&quot;http://www.laputan.org/mud/&quot;&gt;Big Balls of Mud&lt;/a&gt;. They do this for all the typical reasons: subjectively-felt pressure to deliver features sooner, having difficulty articulating the value of cultivating a “better” design, and even not understanding what “better” design even means, and even generic patterns of management dysfunction, including demanding teamwork while rewarding individuals for individual contributions. &lt;strong&gt;Even though you can read thousands of articles about over-investing in design, under-investing remains the norm&lt;/strong&gt;. I’m not complaining: it provides me with an income stream and reminds me of the value in what I do and teach.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;You can read more about understanding and overcoming some of the forces that lead to under-investing in design in &lt;a href=&quot;https://www.thecodewhisperer.com/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;“The Eternal Struggle Between Business and Programmers”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can help your (fellow) programmers debate “better” design more productively through activities such as &lt;a href=&quot;https://www.jbrains.ca/sessions/whats-not-to-like-about-this-code&quot;&gt;“What’s Not To Like About This Code?”&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id=&quot;over-investment-leads-to-wise-investment&quot;&gt;Over-Investment Leads To Wise Investment&lt;/h2&gt;
&lt;p&gt;You might have heard the old joke. It’s an old joke for at least two reasons: it’s corny and it’s right.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Good judgment comes from experience.&lt;/p&gt;
&lt;p&gt;Experience comes from bad judgment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you don’t allow yourself to make questionable choices, then you won’t learn what makes them questionable choices. It’s the difference between “20 years of experience” and “1 year of experience 20 times”. This explains why I don’t try to teach programmers “the right way” to design; instead, I try to teach them a way to discover better ways of designing over time. And not everyone agrees on what constitutes “better” here. I don’t mind.&lt;a href=&quot;#fn5&quot; class=&quot;footnote-ref&quot; id=&quot;fnref5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When writers say “always do X” or “never do X” to programmers about design choices, I worry that they are robbing the readers of an opportunity to develop “good” judgment. Even when those writers don’t explicitly say “always” or “never”, their mere role as influential leaders causes many of their ardent followers to insert the words “always” or “never” in their mind as they read, so they need to be aware of that. This explains why I take great care to distinguish various grades of advice: the things that I tend to do from the things I prefer to do from the things that I almost always do. I almost always use Inbox Technique while I’m working, but I merely tend to write the test first. I prefer to guide designs to evolve by refactoring, but I don’t insist on pushing up-front design decisions out of my mind as though trying to “push away the bad thoughts”. On the contrary, I trust myself to make design decisions up front precisely because I trust myself to refactor away from the decisions that ultimately don’t work as well as I’d expected.&lt;/p&gt;
&lt;p&gt;I wouldn’t have developed this trust and this skill if I hadn’t felt free to over-invest in design on a few projects &lt;a href=&quot;https://groups.io/g/testdrivendevelopment&quot;&gt;with the help of a team of advisers&lt;/a&gt; who guided my learning along the way. Now I have the pleasure of working with others as &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;one of their trusted advisers&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;The usual disclaimers about neurodiversity apply: not everyone will learn this way, but I feel fairly confident that it’s a very very common way for people to learn. I might have this wrong and I would happily accept any research findings that suggest changing my mind.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;One of the various “ring”-style architecture styles, including Hexagonal/Ports-and-Adapters, Onion, and my Universal Architecture. Broadly speaking, these are rules for dependencies between modules (or classes or objects) that tend to reduce the cost of testing and changing code.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Martin has described “architecture” as the set of “irreversible” design decisions. I interpret that to mean design decisions that seem to expensive to change and therefore which we can’t afford to allow to freely emerge. Instead, we need to commit earlier to these design decisions than a Lightweight practitioner would otherwise choose to do.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I tend to use the word “architecture” to an audience that expects me to use it, then immediately frame architecture as “design decision that seem too expensive to change”, after which I feel more confident not using the word at all with them.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn5&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I think of design as the activity of organizing source code in a way that reduces the cost of programmers figuring out how to change it confidently and safely in the future.&lt;a href=&quot;#fnref5&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 09 Jan 2023 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/investing-wisely-in-architecture-through-refactoring</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/investing-wisely-in-architecture-through-refactoring</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>A Matter of Interpretation: Mock Objects</title>
        <description>&lt;p&gt;In the middle of a discussion about test doubles/mock objects and their role in design, someone posted this:&lt;/p&gt;
&lt;figure style=&quot;max-width: 400px&quot;&gt;
&lt;a href=&quot;https://mastodon.social/@danrot/109512760763318130&quot;&gt;&lt;img alt=&quot;A comment about some weaknesses of test doubles/mock objects, with a link to the original comment on Mastodon.&quot; src=&quot;/images/a-matter-of-interpretation-with-mock-objects/inciting-comment.png&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;
Reminder: arguing against a toot does not imply critiquing the tooter.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I’d like to focus on these parts&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“mocks expectations are repeated, if the contract changes you have to change all the expectations”&lt;/li&gt;
&lt;li&gt;“for me building software with ‘real’ parts feels better and more natural. it works, i can see the machine moving, I have more confidence.”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I interpret these two statements in a way that changes how I relate to them. If you’ve struggled with using test doubles as a design tool, then maybe you would find these additional interpretations helpful. Let’s see!&lt;/p&gt;
&lt;h2 id=&quot;remove-duplication&quot;&gt;Remove Duplication!&lt;/h2&gt;
&lt;p&gt;When I see expectations repeated in tests, I look for ways to remove that duplication. &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Removing duplication tends to improve my designs&lt;/a&gt;, even if it sometimes takes some persistence or patience to see those changes as improvements. I have grown to trust that my future self will regret ignoring the design risks that my present self often feels are “not worth the effort” to address right now.&lt;/p&gt;
&lt;p&gt;How to remove that duplication? Two options immediately come to mind, depending on the nature of the duplication.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduce a thin layer around the test doubles to hide the implementation details, &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;revealing intent&lt;/a&gt; and respecting the guidelines of the Universal Architecture.&lt;/li&gt;
&lt;li&gt;Introduce a higher-level abstraction that replaces a group of related expectations with a single expectation. Raising the level of abstraction often simplifies the resulting interactions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For my purposes in writing this article, I don’t need to know how to remove duplication here. Instead, I want to highlight my design process: &lt;strong&gt;I welcome the duplication, because I interpret it as a beneficial refactoring opportunity.&lt;/strong&gt; I routinely work with programmers who don’t interpret the situation this way, but instead copy and paste these expectations from test to test, typically either because they feel stuck or because they feel rushed. Maybe they don’t know how to improve the design, maybe they don’t have the authority, or maybe they can’t justify taking the time. Whatever the reasons, they wouldn’t interpret the duplication as a signal to refactor, but rather as an unavoidable fact of life. A trap.&lt;/p&gt;
&lt;p&gt;I don’t want to criticize anyone’s interpretation. I merely want to mention that I have trained myself to use this duplication as a signal to refactor and I make a conscious decision whether to refactor or not. And I usually refactor, but even when I don’t, I add a &lt;code&gt;REFACTOR&lt;/code&gt; comment to remind my future self what to do when I finally decide to stop resisting. And sometimes future me has an even better idea when it gets there.&lt;/p&gt;
&lt;p&gt;As a result, I see this pattern of duplicating expectations as a strength, not a weakness. I interpret this as test doubles doing their job, not as a drawback to using them. Indeed, &lt;strong&gt;test doubles make this design risk visible and difficult to ignore&lt;/strong&gt; in a way that other forms of Lightweight Implementation sometimes hide. I want that—or at least I’ve grown to like it. Maybe you can, too. You might even like it.&lt;/p&gt;
&lt;h2 id=&quot;it-feels-more-natural-its-more-real&quot;&gt;It “Feels More Natural”; It’s “More Real”&lt;/h2&gt;
&lt;p&gt;Many programmers tell me that it feels more compelling to integrate a module with the production implementations of its neighboring collaborators. They even call those things “the real implementation”, which reinforces the notion that modularity and abstractions are somehow “fake”. I understand where this feeling comes from, even though I don’t share it any more.&lt;/p&gt;
&lt;p&gt;In my work I often encounter programmers with this belief. I sometimes challenge this belief by asking them a question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I assume you write code that uses lists. I assume your language has at least two implementations of lists: one backed by an array and another implemented as a linked list. How confident would you feel about the correctness of your code if I randomly replaced a bunch of array lists with linked lists? (Ignore the execution speed issue. And assume that I changed nothing else.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Almost always they tell me that they don’t mind. They feel equally confident using a linked list implementation compared to an array list implementation.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The next question makes all the difference.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why? Why not insist on integrating everywhere specifically with a consciously-selected implementation of list?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Their answers tend to boil down to this: &lt;strong&gt;“I trust that the implementations of &lt;code&gt;List&lt;/code&gt; that I use respect the Contract of &lt;code&gt;List&lt;/code&gt;.”&lt;/strong&gt; They rarely use those exact words, but they almost always agree with that statement when I say it to them.&lt;/p&gt;
&lt;p&gt;I have experienced a wide variety of the reasons why they trust those implementations of the their list data type&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;, but there is one consequence of that trust that comes up every time: &lt;strong&gt;they think of lists directly as lists (the abstraction) without needing to think about the choice of implementation module (class, object, whatever)&lt;/strong&gt;. They don’t &lt;em&gt;always&lt;/em&gt; think like this, but &lt;strong&gt;it becomes their default way of thinking&lt;/strong&gt;. They tend to consider the implementation details only when they worry about performance characteristics or when they work in a programming language where they can’t delegate memory management to the runtime environment. &lt;strong&gt;Whenever they have the opportunity, they ignore the very existence of different implementations of the abstract type “list”. And they find that freeing.&lt;/strong&gt; So do I!&lt;/p&gt;
&lt;p&gt;Good! Two more questions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Wouldn’t you like to feel that freedom in more parts of your design?&lt;/li&gt;
&lt;li&gt;What stops you from feeling that freedom?&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;That leads us into a discussion of Collaboration and Contract Tests as a way to gain confidence in ignoring the implementation details behind purely abstract data types (also known as interfaces, protocols, or roles). That tends to lead to a discussion about the value of increasing trust in the Contract of their own abstractions and subsequently needing less often to integrate directly with “the real thing”.&lt;/p&gt;
&lt;p&gt;In other words, &lt;strong&gt;if you need to integrate with “the real thing” to feel confident in your code, then you don’t trust the Contract of your neighboring collaborators&lt;/strong&gt;. You can gain that confidence with integrated tests or with contract tests; &lt;strong&gt;you can choose&lt;/strong&gt;. I feel comfortable doing both, although if you don’t trust those Contracts somehow, you’ll find yourself stuck with integrated tests whose cost to maintain only increases (at an accelerating pace!) over time. Give yourself options!&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I don’t experience the other problems that this person reports, but I also don’t feel any need to quibble. They experience what they experience.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Many programmers are even surprised that such a thing is possible! They use lists without even knowing that they’re using a purely abstract type and not a specific implementation. That makes my point even more strongly.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;“The contract is small.” or “I only use a small part of the interface.” or “The implementations have been around for 20 years.” or “The core programmers of the language know what they’re doing.” or “The client base of this interface is huge, so the implementations must work.” or “This abstraction is so central to writing code that if it didn’t work, the language would have disappeared by now.”&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Tue, 27 Dec 2022 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-matter-of-interpretation-with-mock-objects</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-matter-of-interpretation-with-mock-objects</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>What&apos;s Not To Like About This Code? An Experiment.</title>
        <description>&lt;p&gt;Code Reviews have a bad reputation. It seems easy to do them poorly, to create friction, to hurt people, and to waste both time and energy doing them. For this reason, I developed a simple serious game: &lt;a href=&quot;https://www.jbrains.ca/sessions/whats-not-to-like-about-this-code&quot;&gt;“What’s Not To Like About This Code?”&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’m going to practise criticizing code in public. I’ve decided to do this for two key reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It might help readers by making concrete some of the abstract-sounding advice that I provide.&lt;/li&gt;
&lt;li&gt;It might increase the amount of &lt;em&gt;civility&lt;/em&gt; in code criticism in the world, which I hope we can agree sounds like a worthwhile goal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s see what happens.&lt;/p&gt;
&lt;style type=&quot;text/css&quot;&gt;
figure.interstitial img { max-width: 80%; max-height: 2cm;  }
&lt;/style&gt;
&lt;figure class=&quot;interstitial&quot;&gt;
&lt;img src=&quot;/images/icons/noun-dislike-2199212-E36877.png&quot; /&gt;
&lt;/figure&gt;
&lt;h1 id=&quot;episode-1&quot;&gt;Episode 1&lt;/h1&gt;
&lt;p&gt;In a discussion in &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;The jbrains Experience&lt;/a&gt;, someone asked about patterns for handling incoming messages out of sequence, especially when processing Message 1 (the message arriving first) might lead to making data obsolete that Message 2 (the message arriving second) tries to refer to. Another member helpfully mentioned the “Saga” pattern, which I hadn’t seen before, but which seems simple enough: a state machine that governs holding incoming messages in queue until they can be applied. Helpful Person shared &lt;a href=&quot;https://docs.particular.net/tutorials/nservicebus-sagas/1-saga-basics/#exercise-sagas-as-policies&quot;&gt;this tutorial about Sagas in NServiceBus&lt;/a&gt; in order to illustrate the pattern.&lt;/p&gt;
&lt;p&gt;I don’t intend to criticize the pattern, but I noticed something about their code sample that I didn’t like.&lt;/p&gt;
&lt;pre class=&quot;csharp&quot;&gt;&lt;code&gt;private async Task ProcessOrder(IMessageHandlerContext context)
{
  if (Data.IsOrderPlaced &amp;amp;&amp;amp; Data.IsOrderBilled)
  {
    await context.SendLocal(new ShipOrder() { OrderId = Data.OrderId });
    MarkAsComplete();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two things jump out to me right away.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The name &lt;code&gt;ProcessOrder&lt;/code&gt; seems both accurate and misleading at the same time.&lt;/li&gt;
&lt;li&gt;This design choices makes arguably the most important code in this Saga annoyingly difficult to test.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;the-name&quot;&gt;The Name&lt;/h2&gt;
&lt;p&gt;An accurate-but-misleading name &lt;strong&gt;gives me a false sense of understanding the code, but ultimately betrays my trust&lt;/strong&gt;. This code seems to have an intent related to processing an order, but it doesn’t always process an order! It might process an order, if it thinks it should process the order; otherwise, it doesn’t process any order.&lt;/p&gt;
&lt;p&gt;I chose the phrase “betrays my trust” in order to be intentionally overly-dramatic for humorous effect, but there lies a kernel of truth in that. &lt;strong&gt;A name having this effect on me trains me not to trust other names in the code.&lt;/strong&gt; This effect builds over time, adding stress and reducing energy, which tends to lead to further deterioration of the code, which leads to more mistrust. I see a positive feedback loop of pain and suffering, leading at best to numbmess. I prefer not to live like that.&lt;/p&gt;
&lt;h2 id=&quot;holding-business-rules-hostage&quot;&gt;Holding Business Rules Hostage&lt;/h2&gt;
&lt;p&gt;Although written in Tell, Don’t Ask style, this implementation of &lt;code&gt;ProcessOrder()&lt;/code&gt; holds as hostage the part of the code that I imagine we’d care most about testing: the Guard Clause that protects us from trying to process an order before it’s ready to process. When I imagine writing those tests, I imagine before forced to choose between two alternatives I dislike more-or-less equally:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An integrated test that actually tries to process an order.&lt;/li&gt;
&lt;li&gt;An isolated test that sets an expectation on &lt;code&gt;SendLocal()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The integrated test would force me to know about the details of how to detect that this code actually tried to process an order, even though I don’t care about the outcome of processing an order (and I might even need to avoid actually processing the order, because that sounds like a destructive operation!).&lt;/p&gt;
&lt;p&gt;The isolated test would force me to choose between exposing an implementation detail (&lt;code&gt;SendLocal()&lt;/code&gt;) and hiding that behind an abstraction that I might not otherwise want yet. I might actually &lt;em&gt;like&lt;/em&gt; to hide sending a local message behind an abstraction and I might even &lt;em&gt;like&lt;/em&gt; that this design choice has forced me to confront that decision, but even with a nice abstraction to hide &lt;code&gt;SendLocal()&lt;/code&gt;, the resulting tests become more complicated than they need to be: they become coupled to a side-effect and they use “cause side-effect X or not” as little more than a boolean value in a tuxedo. (Where’s that meme when I need it?)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As I look at this code again, just before publishing this article, I am reminded that &lt;code&gt;ProcessOrder()&lt;/code&gt; takes as an argument the “Message Handler Context” collaborator that it sends &lt;code&gt;SendLocal()&lt;/code&gt; to. I infer that this makes &lt;code&gt;ProcessOrder()&lt;/code&gt; an Adapter to the NServiceBus framework that exposes &lt;code&gt;IMessageHandlerContext&lt;/code&gt; and that this interface already is the intended abstraction. I would definitely &lt;em&gt;not&lt;/em&gt; want to wrap the framework’s abstraction in a homegrown abstraction inside a function whose purpose seems to be as an Adapter to the framework. That would seem to defeat part of the purpose of a framework Adapter.&lt;/p&gt;
&lt;p&gt;I digress.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I would rather check the business rule more directly, both because it would seem more resilient to change and it would reveal its intent more clearly. This seems especially important, given that this business rule seems to lie at the center of this code’s existence: to avoid trying to process an order when that operation is doomed to fail. Moreover, this feels like a Broken Window risk: if we don’t attend to this risk now, future changes will only intensify the suffering from the unneccessary coupling/indirectness. The tests will only become more brittle and costly to maintain. This example seems to illustrate the common pattern that we rarely find the time and energy to improve it now, but &lt;strong&gt;we will surely find the time and energy to whine about it in two months&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;theres-more-not-to-like&quot;&gt;There’s More Not To Like…&lt;/h2&gt;
&lt;p&gt;Even though I could find more not to like about this code, I don’t need to do that now. I’ve said what I wanted to say and I feel ready to move on. If you’d like to mention more things not to like, then please feel invited to do that, but please also remember this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you comment in public, remain civil; if you can’t remain civil, then comment in private.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Please.&lt;/p&gt;
&lt;h2 id=&quot;even-so&quot;&gt;Even So…&lt;/h2&gt;
&lt;p&gt;In spite of finding these things not to like about the code, I followed this tutorial about the Saga pattern quite easily, so the tutorial did its job well enough for me today. Please remember that I don’t offer any of this as a criticism of the overall article nor of its authors.&lt;/p&gt;
&lt;p&gt;I merely wanted to point to an example of small code with small risks that I consider worth addressing before they become serious problems. What do you think?&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Dec 2022 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/whats-not-to-like-about-this-code-1</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/whats-not-to-like-about-this-code-1</guid>
        
        
        <category>Refactoring</category>
        
        <category>Simple Design</category>
        
        <category>What&apos;s Not To Like About This Code?</category>
        
      </item>
    
      <item>
        <title>What is &apos;the Right&apos; Amount of Refactoring?</title>
        <description>&lt;p&gt;A mentoring client of mine said this recently:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I took ownership of some strategically pivotal code and did precisely that, typically refactoring twice a week for about 18 months (my delivery was unaffected). The refactorings took at most half an hour. Last week I got reprimanded. I’ve read the room and stopped.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Someone asked why someone reprimanded them, from which came this reply:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I should be refactoring under an initiative, the colleague felt. I said I was refactoring to the &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;Four Rules of Simple Design&lt;/a&gt;. Others felt that is not a valid reason.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’ve experienced this. Let me describe how I handle the situation.&lt;/p&gt;
&lt;h1 id=&quot;two-kinds-of-refactoring&quot;&gt;Two Kinds of Refactoring&lt;/h1&gt;
&lt;p&gt;We have two kinds of refactoring: speculative and purposeful. The purposeful kind happens when we clean up the part of the code that we intend to change next; the speculative kind happens when clean up some part of the code where we have worked recently, hoping that it helps us in the future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Speculative refactoring makes many people nervous&lt;/strong&gt;, because the return on investment is uncertain. Purposeful refactoring makes them feel better, but then the cost is often uncertain, because &lt;strong&gt;Who Knows how bad the code was left by the last person who worked there&lt;/strong&gt;. We do speculative refactoring in part to try to amortize the cost of refactoring over the lifetime of the project.&lt;/p&gt;
&lt;p&gt;When we are Very Far Behind Schedule, speculative refactoring seems like a luxury we can’t afford. No problem! Stick with purposeful refactoring. Eventually, after we get things a bit under control, someone will whine during some purposeful refactoring about how bad the code was left by Some Irresponsible Person in the past. No problem! Let’s spend 30 minutes doing some speculative refactoring at the end of every task in order to avoid being The Irresponsible Person From the Past.&lt;/p&gt;
&lt;p&gt;And so it goes.&lt;/p&gt;
</description>
        <pubDate>Mon, 22 Aug 2022 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/what-is-the-right-amount-of-refactoring</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/what-is-the-right-amount-of-refactoring</guid>
        
        
        <category>Refactoring</category>
        
        <category>Simple Design</category>
        
        <category>Evolutionary Design</category>
        
      </item>
    
      <item>
        <title>What is Refactoring?</title>
        <description>&lt;p&gt;What is refactoring?&lt;/p&gt;
&lt;p&gt;You’d think that, in 2022, we’d have long settled this question already. Yes and no.&lt;/p&gt;
&lt;h1 id=&quot;a-problem&quot;&gt;A Problem&lt;/h1&gt;
&lt;p&gt;I routinely encounter programmers who struggle with refactoring because they become stuck on this central question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m making these kinds of code changes (describes example)… am I refactoring?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They might arrive at this central question because some well-meaning person has looked at what they’re doing and exclaimed, “That’s not refactoring!” To someone trying hard to learn refactoring, who wants the feeling of making progress, this exclamation can come down like a hammer blow to their confidence, even though it’s often meant more as a friendly warning of going off the rails.&lt;/p&gt;
&lt;p&gt;Let’s please be more careful about doing that. Let’s please become more aware of the risk of interfering with the progress of earnest people who want to learn a thing. Let’s do better to balance giving them correct information with facilitating their learning. Let’s especially take care not to make them feel stupid for getting something wrong. Getting things wrong plays a critical role in learning.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;another-problem&quot;&gt;Another Problem&lt;/h1&gt;
&lt;p&gt;Even worse, when our intrepid learner asks whether they are refactoring or not, many well-intentioned and seasoned practitioners (as well as the occasional asshole) tell them that they’re wrong even to ask the question. I’ve been guilty of this in the past.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; They label asking this question “navel-gazing” and a “distraction”. At their best, they want to help by freeing the learner from the shackles of pinpointing a definition of refactoring! It feels so liberating to stop worrying about whether what one is doing right now “is” refactoring by some strict definition and just do it!&lt;/p&gt;
&lt;p&gt;That works very well for people &lt;em&gt;after&lt;/em&gt; they’ve mastered the fundamentals or &lt;em&gt;before&lt;/em&gt; they’ve even noticed the difference, but what about the people who struggle consciously with the fundamentals? They need to feel like they’re practising “the right thing”. They need to use their time wisely. They need feedback regarding whether they “are on the right track”.&lt;/p&gt;
&lt;p&gt;Are &lt;em&gt;you&lt;/em&gt; going to sit there and write code with them for a few hundred hours to give them the reassurance they need and to help them notice when they’ve gone off the rails? No? OK. In that case, they still need to make sense of the state of their own learning and they don’t have you to lean on. What are they supposed to do?!&lt;/p&gt;
&lt;p&gt;Let me use the Dreyfus Model of skill acquisition&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; for a moment to summarize this point: an Advanced Beginner, on the way to becoming Competent, becomes obsessed with rules and decision trees to guide their behavior. &lt;strong&gt;This is a perfectly natural learning path&lt;/strong&gt;. They rely on precise understanding to feel confident in those rules and decision trees. These people in particular benefit from—and indeed crave—precise definitions. A Proficient practitioner, who has started to break free of the bonds of obsessive precision, harms the Advanced Beginner by telling them not to worry about defining precisely a term central to their active learning. Don’t do that! One day, the learners might become Proficient and &lt;em&gt;then&lt;/em&gt; they will feel comfortable worrying less about the details.&lt;/p&gt;
&lt;h1 id=&quot;how-we-got-here&quot;&gt;How We Got Here&lt;/h1&gt;
&lt;p&gt;Partly, it’s Martin Fowler’s fault.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Refactoring (verb): to restructure software by applying a series of refactorings without changing its observable behavior. (&lt;a href=&quot;https://martinfowler.com/bliki/DefinitionOfRefactoring.html&quot; class=&quot;uri&quot;&gt;https://martinfowler.com/bliki/DefinitionOfRefactoring.html&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The trouble comes from the harmless-looking phrase “observable behavior”.&lt;/p&gt;
&lt;h2 id=&quot;thats-impossible&quot;&gt;“That’s Impossible!”&lt;/h2&gt;
&lt;p&gt;An Advanced Beginner or other sufficiently-determined person can point out that, &lt;em&gt;strictly speaking&lt;/em&gt;, almost any non-trivial code change almost always risks changing some kind of observable behavior. Such a person will cite the Uncertainty Principle to prove their point, if pushed hard enough. They conclude that this definition of refactoring, as it stands, can’t have any meaning.&lt;/p&gt;
&lt;p&gt;Some of those people use this as a reason to discount evolutionary design altogether. Whether that hurts the world or not, I consider it a pity. I would prefer that someone abandon evolutionary design for more-significant reasons than this. Some other people use this as a reason to doubt everything they’ve ever learned about refactoring. They panic, wondering if they’ve missed something really foundational that everyone else seems to understand. We don’t need more people with Imposter Syndrome.&lt;/p&gt;
&lt;p&gt;Worse, those of us with significant refactoring experience, who encounter someone objecting this way, might not be able to distinguish the crank (who merely wants to discount evolutionary design, even on a technicality) from the earnest learner (who is struggling to understand a central concept in the topic they’re learning). This leads to two unfortunate outcomes (among others):&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Discouraging the earnest learner by disrupting their learning. (I described this earlier.)&lt;/li&gt;
&lt;li&gt;Perpetuating the notion that refactoring is pseudo-engineering, because we can’t even get our definitions straight! (Some programmers will therefore be scared away and will never know what they’re missing.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can try to fix the problem, but pretty soon we bump up against some immovable limitations of human communication. I’m an amateur philosopher at best, so what follows is my attempt at making sense of what happens. If you’ve read any Wittgenstein, please don’t yell at me. I haven’t and I won’t.&lt;/p&gt;
&lt;h2 id=&quot;you-know-what-i-mean&quot;&gt;You Know What I Mean!&lt;/h2&gt;
&lt;p&gt;Most people most of the time get the inflexion of Martin’s nuance&lt;a href=&quot;#fn5&quot; class=&quot;footnote-ref&quot; id=&quot;fnref5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt;, possibly even accidentally. They grasp that by “observable behavior”, Martin doesn’t literally mean every observable detail, mostly because that’s obviously either impossible or undefined. The very notion of “observable behavior” implies at least three competing meanings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;behavior as observed by one specific observer&lt;/li&gt;
&lt;li&gt;the union of the behaviors as observed by all possible observers&lt;/li&gt;
&lt;li&gt;behavior as observed by reasonable observers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Martin very probably means “reasonable observers”, but our poor Advanced Beginner can be forgiven for jumping straight to one of the other two meanings. Or maybe to being pulled in two different directions by trying to engage both.&lt;/p&gt;
&lt;p&gt;That’s just part of being an Advanced Beginner.&lt;/p&gt;
&lt;p&gt;Indeed, most people most of the time understand that Martin means something more like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Refactoring (verb): to restructure software by applying a series of refactorings without changing &lt;strong&gt;the observable behavior that the project community generally cares about preserving, both at the moment and in general throughout the lifetime of that part of the system&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yeah… it doesn’t exactly roll off the tongue, does it?&lt;/p&gt;
&lt;p&gt;And now we come to &lt;em&gt;my&lt;/em&gt; struggle: how to describe refactoring in a way that achieves all these goals at once:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;people will (fairly easily) remember&lt;/li&gt;
&lt;li&gt;people won’t fight over (much)&lt;/li&gt;
&lt;li&gt;people will find (mostly) helpful&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why do I care? I want the Advanced Beginner to feel the freedom to struggle with the “navel-gazing” that everyone else labels as either a waste of time or, worse, a sign that the entire endeavor is bullshit. And I want more-experience practitioners to retain the freedom to see the discipline as more than a set of rules to follow.&lt;/p&gt;
&lt;p&gt;I generally want less confusion and more freedom.&lt;/p&gt;
&lt;h1 id=&quot;so-what-is-refactoring&quot;&gt;So… What is Refactoring?&lt;/h1&gt;
&lt;p&gt;Let me try to describe refactoring as I understand it.&lt;/p&gt;
&lt;p&gt;First, I see two concepts with the same word:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;refactoring, the discipline of improving the design of existing code safely&lt;/li&gt;
&lt;li&gt;refactoring, an individual code transformation that facilitates refactoring-the-discipline&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wish we didn’t have one word for both of these things, but that’s just how English works. I’ve chosen to find it endearing.&lt;/p&gt;
&lt;p&gt;With these two concepts I like to say that &lt;strong&gt;refactoring (1) is a discipline of improving the design of existing code by judiciously applying refactorings (2) in an environment that tends to optimize for safety&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I characterize refactoring-the-discipline with these features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;changing code incrementally&lt;/li&gt;
&lt;li&gt;keeping the code “working”&lt;/li&gt;
&lt;li&gt;intent to improve the design&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The act of keeping the code “working” corresponds to the idea of “not changing observable behavior”. But since preserving all observable behavior is &lt;em&gt;strictly speaking&lt;/em&gt; impossible to guarantee in general, I focus on keeping the code “working”. Then I use what I learned from Jerry Weinberg about “it works”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Quality is value to some person at some time. (Jerry Weinberg, then &lt;a href=&quot;https://www.shino.de/2010/07/22/quality-is-value-to-some-person-at-some-time/&quot;&gt;Markus Gärtner&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From here, it’s a short walk to defining “it works” to mean “has enough quality at the moment” or, if you prefer, “works well enough”. No matter how we articulate it, we can’t escape the notion that “works” depends on the people doing the judging. And those people’s judgments—their ideas, their needs, their points of focus—change over time.&lt;/p&gt;
&lt;p&gt;And this corresponds exactly to the problem of “without changing observable behavior”. Which observers? When? And what are they paying attention to? Surely we can’t &lt;em&gt;possibly&lt;/em&gt; mean an omniscient, omnipresent observer, because if we did, then refactoring would become impossible… &lt;em&gt;strictly speaking&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The phrase “without changing observable behavior” suffers from an apparent precision that it can’t deliver. For that reason, I prefer to say things like “preserves the behavior we care about” or “continues to work similarly enough to satisfy the project community” or some similar phrase. I want to avoid arguing about “observable behavior” by placing the observers at the center of the discussion. Only the observers know what they’re observing!&lt;/p&gt;
&lt;p&gt;Well… if anyone can know, only they can know.&lt;/p&gt;
&lt;h1 id=&quot;so-what-is-a-refactoring&quot;&gt;So… What is &lt;em&gt;a&lt;/em&gt; Refactoring?&lt;/h1&gt;
&lt;p&gt;I like to say that &lt;strong&gt;a refactoring (2) is a code transformation that preserves enough observable behavior to satisfy the project community&lt;/strong&gt;. I’d like to note here that a refactoring might or might not improve the design. We can perform refactorings (2) outside of refactoring (1).&lt;a href=&quot;#fn6&quot; class=&quot;footnote-ref&quot; id=&quot;fnref6&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Even this description often leads to discussions about what it means to satisfy the project community, who the project community includes, and what it means to satisfy them “enough”. I love these discussions, because they tend to have (at least) two key outcomes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;they shatter illusions about the “correctness” and “readability” of code as properties of the code itself, which reduces arguments about angels and dancing and pins&lt;/li&gt;
&lt;li&gt;they bring to the surface unstated assumptions and lingering disagreements that tend to manifest as prioritization battles, needless context switches, and other symptoms of divergent, incompatible goals&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;cant-you-make-this-simpler&quot;&gt;Can’t You Make This Simpler?!&lt;/h1&gt;
&lt;p&gt;Nope.&lt;/p&gt;
&lt;p&gt;Simple-but-wrong or precise-and-complex. &lt;strong&gt;Pick one&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This article seeks to explain why, on the one hand I care about “getting it right” and on the other hand I don’t blame people for “getting it wrong”. (I don’t even really like to say “getting it wrong”, but that works better as a rhetorical device.) Martin’s published definition of refactoring works well enough for most people most of the time, but in certain specific contexts it creates repeatable and non-trivial problems. I happen to spend quite a lot of time in those contexts, so I feel the consequences more. And that’s why the responsibility falls to me (and others in my situation) to try to soften the blow.&lt;/p&gt;
&lt;p&gt;And that’s just how language works. And that’s just how learning works. And that’s just how humans work.&lt;/p&gt;
&lt;p&gt;Same as it ever was.&lt;/p&gt;
&lt;p&gt;It’s fine.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;When retrieving information, if we struggle a bit to recall something, and occasionally get it wrong, we strength the corresponding neural pathways better and more quickly than if we always recall things correctly and easily. Brains are weird.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Sorry. Truly.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;This model remains controversial, but please let me use it lightly to make this point a bit easier to fit into one’s mind.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;For once, we can’t blame Chet.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn5&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;A line I learned from a Benny Hill sketch. Nevermind, unless you chuckled.&lt;a href=&quot;#fnref5&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn6&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I’ve tried letting the notion of a refactoring (2) imply intent to improve the design, and it makes discussing the topic too difficult. Removing this assumption seems to result both in cleaner writing and cleaner reasoning. I consider a refactoring (2) as a neutral code transformation, while refactoring (1) must by definition involve at least attempting to improve the design.&lt;a href=&quot;#fnref6&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Fri, 29 Jul 2022 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/what-is-refactoring</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/what-is-refactoring</guid>
        
        
        <category>Refactoring</category>
        
        <category>Simple Design</category>
        
        <category>Evolutionary Design</category>
        
      </item>
    
      <item>
        <title>Why Refactoring Is Not Always a Code Smell</title>
        <description>&lt;p&gt;Someone is circulating a talk—a &lt;em&gt;concise&lt;/em&gt; one, which I appreciate—entitled “Refactoring is a code-smell” (sic). Before I continue, let me make a few things clear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I do not wish to shame nor criticize the speaker. Their talk triggered this article, but…&lt;/li&gt;
&lt;li&gt;I have not seen the talk; I’ve only been given one viewer’s impression it and…&lt;/li&gt;
&lt;li&gt;I am not trying to rebut/refute this talk, but rather I want to say a few things about the claim as I understand it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please take a moment before you comment in anger. I want to read your comments, but not your fury.&lt;/p&gt;
&lt;h1 id=&quot;before-we-begin&quot;&gt;Before We Begin&lt;/h1&gt;
&lt;p&gt;When I read “Refactoring is a code smell”, I imagine at least three ways to understand this statement.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Refactoring is never a good idea. (“Refactoring is &lt;em&gt;always&lt;/em&gt; a code smell”)&lt;/li&gt;
&lt;li&gt;Refactoring is a risk and therefore not a universal good. (Code smells, after all, are risks.)&lt;/li&gt;
&lt;li&gt;If we’re refactoring, then we’re not satisfied with the design.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don’t know which of these the speaker intends.&lt;/p&gt;
&lt;h1 id=&quot;refactoring---not-satisfied&quot;&gt;Refactoring -&amp;gt; Not Satisfied&lt;/h1&gt;
&lt;p&gt;I am never entirely satisfied with any of my designs, at least not the ones that emerge in industrial-strength situations under the stress of delivering to (helpfully) impatient customers. &lt;strong&gt;This is intentional.&lt;/strong&gt; If I were entirely satisfied with every aspect of the design of a system, then likely one of the following would be true:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The system is so small that the design doesn’t much matter.&lt;/li&gt;
&lt;li&gt;I have over-invested in designing the system.&lt;/li&gt;
&lt;li&gt;I have been working on the system for so long and it’s so valuable that I could safely over-invest in designing the system without significant risk to profit on the project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How else might it happen? Nothing comes immediately to mind. Please feel invited to share your story.&lt;/p&gt;
&lt;p&gt;When I guide designs to evolve, I try to invest as little as possible in reducing volatility in the marginal cost of features. In other words, I try to design just well enough to avoid nasty surprises in the cost of adding the next feature. Refactoring helps me do this, because I can defer design choices until I feel very confident that a feature would benefit from them. (Of course, some design choices require so little extra effort that &lt;em&gt;a little&lt;/em&gt; premature design optimization won’t hurt much. It’s like buying very cheap lottery tickets that win more often.) By adopting a strategy of refactoring, I can confidently design in a way that doesn’t rely on accurately predicting the sequence of future features. This gives my customers more flexibility to choose features while incurring a less-surprising (and often quite low) extra cost.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now is a great time to say this&lt;/strong&gt;: If you know the next 20 features with near-certainty, then you can safely “design ahead”. Go for it! Big risk, big reward. Go with your gut. I’m not going to tell you not to do it, although I would probably ask you many questions about how you arrived at that near-certainty. If you could convince me that you weren’t dreaming, I’d go with you.&lt;/p&gt;
&lt;p&gt;Since I’m never quite satisfied with the design, I refactor continuously. This allows me to pretend that I always made “just the right design decisions” at every step of the process.&lt;/p&gt;
&lt;p&gt;When I say “refactoring continuously”, I don’t mean intentionally making the same design “mistakes” over and over, then refactoring towards a more-sensible design. Instead, I mean “continuously challenging my assumptions about whether I need these extra elements of the design and erring on the side of deferring decisions”. Some people who first learn about refactoring react like this: “Why should I ignore all my accumulated wisdom? Sometimes the right design is obvious!” Yes. If you know that MVC will fit this feature, then I see no need to force yourself to “go the long way” and guide MVC to emerge for the 718th time in your career. In that case, I’ll usually start with an MVC design and use Client-First Design with Test Doubles to build that part of the system… as long as I feel perfectly comfortable refactoring &lt;em&gt;away&lt;/em&gt; from MVC when I sense that it’s more trouble than it’s worth.&lt;/p&gt;
&lt;p&gt;And that’s the key: when I refactor, I’m allowing myself to be wrong about my design choices without disastrous consequences. And when I’m allowed to be wrong, I don’t need to agonize up front about making the right choice. I can make confident progress sooner, secure in the knowledge that the design rarely falls off a cliff. From time to time, I sigh at some of the refactorings I need to perform, but I start absolutely crying when I realize that I’ve made a fundamental design mistake &lt;strong&gt;and&lt;/strong&gt; I’ve duplicated it all over the place. Some refactoring along the way would have limited the damage.&lt;/p&gt;
&lt;p&gt;That’s what refactoring is for: to limit the damage of making a design decision with imperfect information; to limit the damage of making even a design &lt;em&gt;mistake&lt;/em&gt;; to allow us to break free of paralyzing doubt due to uncertainty about which features are coming next.&lt;/p&gt;
&lt;p&gt;That really doesn’t sound like a code smell to me.&lt;/p&gt;
&lt;p&gt;Unfortunately, it also means that I’m never satisfied with the design: there are always ways to improve the design and I never polish it to perfection because I have more-urgent things to do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now is a good time to point out&lt;/strong&gt; that “there are always ways to improve the design” seems to say something very similar to “there are code smells”. From here, it might not be so difficult to conclude “refactoring is a sign that there are code smells”. And from there, it is not so hard to imagine shortening this to “refactoring is a code smell”. I think the last step loses quite a lot in the translation, but I could see myself making that mistake and not noticing it.&lt;/p&gt;
&lt;h1 id=&quot;refactoring-itself-carries-risk&quot;&gt;Refactoring Itself Carries Risk&lt;/h1&gt;
&lt;p&gt;Indeed so. Refactoring means changing code and that is inherently risky, so we’d better have at least two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A clear understanding of and agreement about the reasons to refactor this code right here right now.&lt;/li&gt;
&lt;li&gt;Good refactoring skill, meaning that we can refactor swiftly, safely, and accurately.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It would be safer to get the design right the first time. Unfortunately, &lt;strong&gt;I don’t know how to do that&lt;/strong&gt;—at least not always. Certainly, there are some situations where simply installing a design pattern works better.&lt;/p&gt;
&lt;section class=&quot;highlight&quot;&gt;
&lt;p&gt;I wrote some parsing software in 2022 and I wanted to guide my design to evolve in the direction of Parser Combinators, because I had watched some videos about them and thought they would fit the design well. I chose to experiment with refactoring towards Parser Combinators, but I made an elementary mistake about the universal type signature of the &lt;code&gt;parse()&lt;/code&gt; function. (I had the &lt;code&gt;Either&lt;/code&gt; in the wrong place.) Correcting this required delicate surgery that felt stressful and took too long. If I had done this for a paying customer, I’d have regretted the choice and felt like I’d wasted some of their money. It would have been better to start with the Parser Combinator pattern up front.&lt;/p&gt;
&lt;p&gt;Fortunately, this was a volunteer project and I chose to use it as an opportunity to experiment and learn. On that basis, I don’t regret my decision, in part because I saw how to refactor towards the Parser Combinator pattern and because I sharpened my skills at removing duplication, which will probably help me in the future.&lt;/p&gt;
&lt;p&gt;Now I know with confidence how to design parsers in a way to make them freely composable. I &lt;em&gt;understand&lt;/em&gt; it. This happened, in part, because I let myself get it subtly wrong. Exercising good judgment comes from experience, which emerges from exercising bad judgment.&lt;/p&gt;
&lt;/section&gt;
&lt;p&gt;If we absolutely can get the design right the first time, then I don’t mind taking a bigger step, jumping to the conclusion, and engaging in some slightly bigger design up front… &lt;strong&gt;as long as I feel comfortable changing my decisions in light of new information&lt;/strong&gt;. This is where I see programmers often become stuck. They make a plan, it seems right, it’s maybe 80% right, but then when that other 20% becomes a problem, they stubbornly refuse to change their plan. Call it Sunk Cost Fallacy, call it whatever you want. &lt;strong&gt;Refactoring skill means developing confidence in changing the design and acceptance that changing the design is inevitable.&lt;/strong&gt; There are other ways to develop that confidence and attitude, but refactoring is one way to do it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now is a good time to point out&lt;/strong&gt; the difference between refactoring as a way of safely changing design decisions and always “taking the long way”. I don’t want programmers to insist on letting every element of the design evolve from first principles, simply because “otherwise it’s not evolutionary design”. &lt;strong&gt;I encourage programmers to learn this way, but not to practise forever this way&lt;/strong&gt;. Most programmers benefit from a period of unlearning bad habits and becoming aware of unstated assumptions they make about the design. In the process, they start by challenging their intuition, even denying it at times, volunteering to “take the long way”. But not forever! As your habits and perspective change, I encourage you to experiment with a little more design up front, bigger steps, and jumping to conclusions. You don’t have to reprove every theorem you use in mathematics from first principles and you don’t have to guide every element of the design to evolve from scratch.&lt;/p&gt;
&lt;p&gt;It’s a good idea to know how to do that. It’s even a good idea to make that your default way of working when under extreme stress. But &lt;strong&gt;refactoring is not a purity discipline&lt;/strong&gt;. You get points&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; for delivering features sooner and more predictably, not for making the design as lean as theoretically possible.&lt;/p&gt;
&lt;p&gt;And maybe that’s a way that refactoring could become seen as a code smell: it’s a sign that we’re constantly taking the long way even thought we know a shortcut and have taken the shortcut successfully many times before. Why refuse the shortcut if it’s safe?! Take it! I would probably call this something other than a “code smell”, but since it’s related to code, I can imagine someone describing it as a “code smell” in the semse of “smell related to code”. The code smell, in this case, would be the need to improve the design of code that we already knew how to design well.&lt;/p&gt;
&lt;h1 id=&quot;refactoring-bad&quot;&gt;“Refactoring Bad!”&lt;/h1&gt;
&lt;p&gt;This one’s easy, because it’s trivially wrong. Refactoring is absolutely positively not a universally bad thing. At a minimum, refactoring provides a mechanism for learning and deeply internalizing the principles of “good” software design much in the same way that one can learn to speak a language. It’s a form of the “Natural Method”: starting with trial and error and gradually accumulating patterns that help speed up the process. Learning “good” software design using the Natural Method isn’t universally good, but it’s also clearly not universally bad. It might not be optimal, but it’s widely successful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now is a good idea to point out&lt;/strong&gt; that I might be falling prey to Survivorship Bias, Cargo Cult thinking, and plenty of Retrospective Rationalization. I agree. I guess we’ll never know. That also means that I’d better not present refactoring as a guaranteed path to success. And so I don’t. I commit to not presenting refactoring as a universal good and I hope you commit to not presenting refactoring as a universal evil.&lt;/p&gt;
&lt;p&gt;Deal?&lt;/p&gt;
&lt;h1 id=&quot;so&quot;&gt;So…?&lt;/h1&gt;
&lt;p&gt;So… is refactoring a code smell? No, but also yes. I can understand why someone would label refactoring a code smell, but I worry that that label reflects an overly-broad meaning of “code smell” or an overly-narrow meaning of “refactoring” or reflects common failure modes and attributes those failures to the technique instead of to the programmer’s stage of learning/competence. To say that refactoring &lt;strong&gt;is&lt;/strong&gt; a code smell seems more imprecise than wrong, but damaging due to its seeming certainty.&lt;/p&gt;
&lt;p&gt;Let me put on my giraffe ears&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; for a moment. Refactoring is a code smell in the sense that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the need to refactor means that the code has smells in it;&lt;/li&gt;
&lt;li&gt;refactoring carries risk, because we change the code more often than we would otherwise need to;&lt;/li&gt;
&lt;li&gt;some programmers never seem to progress past the Advanced Beginner stage of refactoring&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I offer the following replies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When &lt;em&gt;doesn’t&lt;/em&gt; the code have smells in it?&lt;/li&gt;
&lt;li&gt;If we refactor frequently, don’t we ever learn to change the code more safely?&lt;/li&gt;
&lt;li&gt;I’ve seen the same phenomenon, whose causes often lie in the working environment, and in particular in the programmer’s shyness about struggling, making mistakes, and asking for help.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Refactoring isn’t a code smell and it isn’t magic. I’ve used it as a learning mechanism, as a source of freedom in making design decisions, and ultimately as a way to reduce volatility in the marginal cost of features. And I believe you can, too.&lt;/p&gt;
&lt;p&gt;And if you can get those things another way, you should do &lt;em&gt;that&lt;/em&gt; instead. No problem at all; I get paid the same.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;In the context of professional software development, we call those points “currency units”. Your local country or territory has a special name for them. I’m happy with dollars (the Northern ones) and euro.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Search the web for “giraffe ears nvc”. Here, “nvc” refers to “nonviolent communication”.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Wed, 08 Jun 2022 12:49:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/why-refactoring-is-not-always-a-code-smell</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/why-refactoring-is-not-always-a-code-smell</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>Stepping Around a TDD Roadblock</title>
        <description>&lt;blockquote&gt;
&lt;p&gt;I think a lot of people fall off the TDD wagon because of this exact thing—they learn TDD by working on new code and then can’t seem to apply it to their existing work projects. And then they give up, naturally!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When this happens, I help the person focus on the difference between “test-first” and “test-driven”. I hope that this offers them more-realistic expectations regarding the outcome.&lt;/p&gt;
&lt;p&gt;With test-first, we focus on correct behavior and fix defects. Usually, but not always, when we find defects, we are happy to fix them.&lt;/p&gt;
&lt;p&gt;With test-driven, we consider good design and fix dependency problems. Usually, but not always, when we find unhealthy dependencies, we are unhappy because we feel trapped by bad decisions.&lt;/p&gt;
&lt;p&gt;I try to warn people that this will happen, it’s normal, it’s natural, and probably even unavoidable. We need to train ourselves to remember Ron Jeffries’ words “That’s good news about today, not bad news about yesterday”. And since that often sounds trite in the moment, we have a tendency not to believe it. It helps if we support each other to remember these words. Even I don’t believe them every time I hear them, although with enough emotional distance from the situation, I end up trusting them again.&lt;/p&gt;
&lt;p&gt;This is also why &lt;strong&gt;I emphasize practising refactoring and evolutionary design where it’s already easy&lt;/strong&gt;: on code that runs entirely in memory and over which you have enough authority to change it. It might not feel as satisfying to practise there, but it tends to work better (for most people most of the time). One obvious goal emerges: gradually and relentlessly expand our sphere of influence and the Happy Zone&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope that helps them. I don’t know. They tend to disappear on me before I can find out. (That’s the life of a consultant.)&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;My name for what others call “the core” of their design: the part that runs entirely in memory and, in many cases, consists of only pure functions.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 11 Apr 2022 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/stepping-around-a-tdd-roadblock</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/stepping-around-a-tdd-roadblock</guid>
        
        
        <category>Evolutionary Design</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>Which Kinds of Tests Should I Write?</title>
        <description>&lt;p&gt;Too many people are writing too many articles trying to direct others’ thinking on their own testing strategies. &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;I am guilty of this&lt;/a&gt; and would like to contribute to reversing this trend.&lt;/p&gt;
&lt;p&gt;Instead:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;test until fear is transformed into boredom (Phlip Plumlee)&lt;/li&gt;
&lt;li&gt;if you don’t like something about the test, then try interpreting that as a sign of a design problem—usually an unhealthy dependency in the production code (The “driven” in test-driven development)&lt;/li&gt;
&lt;li&gt;faster-running tests tend to provide more value because they shorten the feedback cycle, so if you’re not sure what else to do, try to make tests execute more quickly (Lean thinking)&lt;/li&gt;
&lt;li&gt;when in doubt, write another test (Common sense)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you do these things, then you’ll discover the tests that you need.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; You can do this.&lt;/p&gt;
&lt;p&gt;In the final analysis, remember that &lt;strong&gt;we test in order to gain confidence&lt;/strong&gt; and that &lt;strong&gt;they pay us to generate profit, not to write tests&lt;/strong&gt;.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you’re thinking of a test that will help you gain confidence, then just write it. If you’re thinking of a test that’s clearly more expensive than dealing with the fallout from the corresponding defect, then don’t bother.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That’s enough.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;You’ll sometimes feel strange. You’ll sometimes encounter choices that follow these guidelines, but feel wrong. When that happens, ask a trusted adviser for help.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;OK, this part is complex, so it’s subject to endless debate. Even so, I think you can agree that most people, most of the time are paid by their employers to “produce value” and that tests are &lt;em&gt;an investment&lt;/em&gt; in producing more value per unit time and not the valuable product itself.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;If you don’t trust your own judgment yet, then give yourself the chance to gather more experience. And remember that good judgment comes from experience, while experience comes from bad judgment.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 03 Apr 2022 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/which-kinds-of-tests-should-i-write</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/which-kinds-of-tests-should-i-write</guid>
        
        
        <category>Microtechniques</category>
        
        <category>Evolutionary Design</category>
        
        <category>Refactoring</category>
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>The Saff Squeeze</title>
        <description>&lt;p&gt;I like it when programming feels boring. I prefer to save the excitement for the actually difficult parts of the job of developing software: understanding what to try to build, navigating people, negotiating plans, all that stuff. When it comes time to write code, I’d like that to be exactly the right kind of boring: I want things to work, I want to make steady progress, and I want to know what’s left to do.&lt;/p&gt;
&lt;p&gt;Defects interfere with this rhythm.&lt;/p&gt;
&lt;p&gt;When something behaves in an unexpected way, my emotions become heightened. I suddenly notice all the delicate information crammed into my working memory at risk of being lost to history. My breathing changes. Everything stops. In that moment, I want a &lt;em&gt;system&lt;/em&gt;. The Saff Squeeze is part of that system.&lt;/p&gt;
&lt;p&gt;Here is the Saff Squeeze in one sentence: &lt;strong&gt;inline parts of a failing test until the reason for the failure becomes obvious&lt;/strong&gt;. Now you know enough to be able to do it, but if you’d prefer some detailed instructions, read on.&lt;/p&gt;
&lt;h1 id=&quot;when&quot;&gt;When?&lt;/h1&gt;
&lt;p&gt;I use this technique when I discover a defect and I don’t know what’s causing it. Most often, this means that I make the mistake at some unknown point in the past and am only now encountering it. I’m hunting for the test that I failed to write (or wrote incorrectly) at some point in the past.&lt;/p&gt;
&lt;p&gt;Sometimes, however, I use this technique when I’m adding behavior with a new, intentionally failing integrated test, but I’m not sure where to add the behavior. This technique helps me find a failing microtest that corresponds to my failing integrated test. I generally prefer to work with smaller tests over bigger tests, but I’m often forced by circumstances to work with bigger tests. I digress.&lt;/p&gt;
&lt;h1 id=&quot;how&quot;&gt;How?&lt;/h1&gt;
&lt;p&gt;Start with a failing test—any failing test.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Run the test and watch it fail. Commit. You’ll almost certainly squash later.&lt;/li&gt;
&lt;li&gt;Inline the action of the test. This often requires raising the visibility of internal parts of a module, so do it. Don’t worry about weakening the design for now.&lt;/li&gt;
&lt;li&gt;Look for intermediate assertions to add, such as checking the condition of an &lt;code&gt;if&lt;/code&gt; statement. Add assertions as “high” in the test as possible. We are looking for a new assertion to fail earlier in the test.&lt;/li&gt;
&lt;li&gt;Once the failure moves earlier in the test, commit. You’ll squash later.&lt;/li&gt;
&lt;li&gt;Prune away unnecessary parts of the test, such as paths of &lt;code&gt;if&lt;/code&gt; statements that don’t execute and all the code after the first failing assertion. Commit. You’ll squash later.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do you now understand the cause of the defect? If yes, document it and decide how to fix it. If no, try another iteration of the steps.&lt;/p&gt;
&lt;p&gt;At some point, you’ll find “the missing test”. This is a test that you probably wish that someone had written at some point in the past. We don’t need to blame anyone, even though we might want to. We have found a missing test. We can interpret that as good news about today, not bad news about yesterday.&lt;/p&gt;
&lt;p&gt;Don’t rush. Take a moment. Write things down. Breathe. Now decide how to proceed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maybe squash all these commits, because they add up to “here’s a failing test we should have written before; we’ll make it pass now”. The project history makes it look the same as if we’d always planned to test-drive this behavior today.&lt;/li&gt;
&lt;li&gt;Throw away all those commits, then test-drive the missing behavior using the notes you wrote when you documented the cause of the defect and how to fix it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I imagine there are other options, but I’m not sure what they are right now. Maybe there aren’t.&lt;/p&gt;
&lt;h1 id=&quot;why&quot;&gt;Why?&lt;/h1&gt;
&lt;p&gt;I like having a record of the failing tests, from which I can document both the cause and the resolution of the problem. I can also use the Saff Squeeze to turn bigger tests into smaller ones: I often Squeeze in order to uncover the microtest that I wanted to write, but couldn’t think of how to write.&lt;/p&gt;
&lt;p&gt;Raising the visiblity of internal parts of a module sometimes points me directly to encapsulation choices that seemed sensible at the time, but didn’t work out in retrospect. This provides valuable design feedback that guides me to adjust the boundaries between modules: breaking things apart and extracting new interfaces.&lt;/p&gt;
&lt;p&gt;I like how orderly it feels to do this. It feels like steady progress. It feels exactly the right kind of boring, which helps me think more clearly.&lt;/p&gt;
&lt;p&gt;I love how autonomic most of the steps are. I don’t need to understand anything about the code to Squeeze accurately; it’s enough merely to understand the programming language. I need to know how to inline functions, identify dead code, add assertions at every branch point, and remove the dead code. That’s it. I can practise those things every day, then perform them accurately and safely under pressure. I frequently experience it when I Squeeze that I have no idea what the failing test even &lt;em&gt;means&lt;/em&gt;, then gradually I understand the cause of the problem with crystal clarity. No “talent” required. I imagine that Kent Beck had this kind of thing in mind when he labeled himself “a decent programmer with excellent habits”.&lt;/p&gt;
&lt;h1 id=&quot;the-name&quot;&gt;The Name&lt;/h1&gt;
&lt;p&gt;Kent Beck named the Saff Squeeze for David Saff, who showed him the technique while they worked on JUnit 4. That’s the folklore version, since I wasn’t there when it happened. Maybe something completely different happened; you’d have to ask Kent.&lt;/p&gt;
&lt;h1 id=&quot;no-example-just-do-it&quot;&gt;No Example: Just Do It&lt;/h1&gt;
&lt;p&gt;You want to see an example. I understand. Don’t bother. Just try it. Worst case, you throw away the commits and try again later. It’s really not mysterious. Just follow the steps. If any step seems unclear when you try it, then find me and ask me—maybe I need to clarify something in this article.&lt;/p&gt;
</description>
        <pubDate>Mon, 28 Mar 2022 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-saff-squeeze</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-saff-squeeze</guid>
        
        
        <category>Tutorials</category>
        
      </item>
    
      <item>
        <title>Polynomial Kata in 46 Commits</title>
        <description>&lt;p&gt;I noticed that &lt;a href=&quot;https://ronjeffries.com/articles/-z022/strawberries/-z00/sb-009/&quot;&gt;Ron Jeffries had written about a kata I hadn’t tried before&lt;/a&gt;, so I decided to try it. The exercise involves evaluating a polynomial of one variable at a single point.&lt;/p&gt;
&lt;p&gt;For example: 5x&lt;sup&gt;3&lt;/sup&gt; + 4x&lt;sup&gt;2&lt;/sup&gt; + 19x + 3 at the point x = 5 evaluates to 823. Check my arithmetic if you like.&lt;/p&gt;
&lt;p&gt;How does one write this incrementally and test-first? First things first: if you’ve never tried it, and especially if you’re new to test-first programming, then try it yourself. Take small steps and never write new production code without a failing test.&lt;/p&gt;
&lt;p&gt;If you’d like to follow along commit-by-commit, then visit &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable&quot;&gt;this Git repository&lt;/a&gt;. Let me share the highlights.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The “Browse the code” links go to specific files at Github. If you change the URL in your address bar from &lt;code&gt;github.com&lt;/code&gt; to &lt;code&gt;github.dev&lt;/code&gt;, then you’ll be able to browse the code in a browser-based version of VS Code. Enjoy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;property-based-testing&quot;&gt;Property-Based Testing&lt;/h1&gt;
&lt;p&gt;I often start with a concrete example, then want to expand the example to check all possible inputs. Property-based testing helps me do that. I used &lt;a href=&quot;https://jqwik.net&quot;&gt;jqwik&lt;/a&gt; for this. I find it easy to start with a concrete example, then generalize if it’s safe. Sometimes the property I would check is as difficult to describe as the implementation that would pass the tests, in which case I use concrete examples in place of property-based tests.&lt;/p&gt;
&lt;p&gt;I started with the constant case: the polynomial 5 at the point 2 evaluates to 5. Moreover, it evaluates to 5 at all points. The corresponding property seemed easy to write. (&lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/4c3905f21925b31fa60ebd4542d5b294e792cbcc/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;Browse the code&lt;/a&gt;) So far, we can hardcode the answer and it suffices to have thrown all the inputs together into the Junk Drawer called &lt;code&gt;polynomialOfAt()&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;improve-the-api&quot;&gt;Improve the API&lt;/h1&gt;
&lt;p&gt;When I tried to write the next test, I quickly noticed a weakness in the API, so I chose that moment to separate the coefficients of the polynomial from the desired evaluation point. I chose arbitrarily to represent the coefficients “backwards”: the first element is the 0th position, the second element is the 1st position, and so on. Looking back, I don’t think this made the solution any nicer or any less nice. (&lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/fec4f5550ba51299eac8da84cc7ff80496489544/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;Browse the code&lt;/a&gt;)&lt;/p&gt;
&lt;h1 id=&quot;crank-out-the-permutations&quot;&gt;Crank Out the Permutations&lt;/h1&gt;
&lt;p&gt;Next, I added the linear cases. I added one non-zero coefficient at a time. This helped me sneak up on the solution with no stress.&lt;/p&gt;
&lt;p&gt;Throughout this kata I followed this pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add new behavior with “&lt;code&gt;if&lt;/code&gt; it’s the old situation, do whatever was already there; &lt;code&gt;else&lt;/code&gt; do the new thing”, hardcoding the literal value for “the new thing”&lt;/li&gt;
&lt;li&gt;replace the hardcoded literal value with a calculation, if it’s obvious&lt;/li&gt;
&lt;li&gt;try to collapse branches of the &lt;code&gt;if&lt;/code&gt; statement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although this might seem like overkill for a simple problem, this approach helps me add behavior with less stress in situations where I genuinely don’t yet see the pattern, so I have come to trust it. I committed after each step, so that you can see how I did it.&lt;/p&gt;
&lt;p&gt;I first implemented the case &lt;strong&gt;ax&lt;/strong&gt;, then I implemented &lt;strong&gt;ax+b&lt;/strong&gt;. &lt;a href=&quot;https://github.com//jbrains/evaluate-polynomial-of-one-variable/blob/dcc9592e7194113876593c0bd236d64395c3dba3/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;By this point&lt;/a&gt; I had polynomials of degree 1 working.&lt;/p&gt;
&lt;h1 id=&quot;uh-zero&quot;&gt;Uh… Zero!&lt;/h1&gt;
&lt;p&gt;I quickly realize that I’d forgot about 0, so I attended to that next. There is only one “empty” polynomial and it evaluates to 0 at all points. First I wrote a concrete example, then generalized it to a property. (&lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/566ff9a0b2daf84e353c545cf3eb9761e9fe2b7f/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;Browse the code&lt;/a&gt;)&lt;/p&gt;
&lt;h1 id=&quot;vavr&quot;&gt;Vavr!&lt;/h1&gt;
&lt;p&gt;At this point I knew I wanted to start taking advantage of a nicer collections library, so I installed &lt;a href=&quot;https://vavr.io&quot;&gt;vavr&lt;/a&gt; and migrated away from a naked Java array to a Vavr List. I freely admit that for an exercise this simple, such a decision is overkill; however, I like the libraries I like.&lt;/p&gt;
&lt;p&gt;I used the technique that I learned from Kent Beck decades ago:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Add the new thing&lt;/li&gt;
&lt;li&gt;Migrate the clients&lt;/li&gt;
&lt;li&gt;Remove the old thing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Step 0, if you like, involves &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/eec1289442edad13eb2d98f5775c90f2ae70a9f6/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;renaming something to make room for the new thing&lt;/a&gt;. I like to use the trick of renaming &lt;code&gt;blah&lt;/code&gt; to &lt;code&gt;legacyBlah&lt;/code&gt; in order to make room for the new thing that I’d prefer to call &lt;code&gt;blah&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In this case, I &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/119aa1d43791ea216ab0b7702c50ac2104abab15/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;combined steps 1 and 2 into the same commit&lt;/a&gt;. Then &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/44924f4d17afaa01cae7d879d82dd7b67a477a5a/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;I performed step 3 in its own commit&lt;/a&gt;. Finally &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/a86915061edc25eb15ae8ca896846c16e0a332f5/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;I cleaned up before moving on&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;make-similar-code-more-similar&quot;&gt;Make Similar Code More Similar&lt;/h1&gt;
&lt;p&gt;From here, I used a few fundamental tricks to continue:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Add behavior incrementally by adding non-zero coefficients one at a time.&lt;/li&gt;
&lt;li&gt;First hardcode the answer, then replace literal values with expressions, working from the output towards the input.&lt;/li&gt;
&lt;li&gt;Made similar code more similar in order to make duplication easier to stop, then remove.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once I had degree-2 polynomials working, I mostly made similar code more similar until I could sense a pattern of recursion. After &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/334d77c441d2db530d7fd18c6d30a65ffd358b7a/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;scrambling to make the degree-2 case work&lt;/a&gt;, I just kept making similar code more similar commit by commit until &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/de1e23594ecfde93fa458cc3ada4b704404bbedb/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;similar code became identical&lt;/a&gt;. At that point, it felt easy to remove the duplication.&lt;/p&gt;
&lt;h1 id=&quot;remove-duplication&quot;&gt;Remove Duplication&lt;/h1&gt;
&lt;p&gt;From this point, I mostly removed duplication until I felt satisfied that there was none left to remove. At the same time I replaced recursion with iteration for computing &lt;strong&gt;x&lt;sup&gt;n&lt;/sup&gt;&lt;/strong&gt; and I improved some names by using conventional terms from the domain of mathematics.&lt;/p&gt;
&lt;h1 id=&quot;degree-3&quot;&gt;Degree 3?&lt;/h1&gt;
&lt;p&gt;By the time I reached degree-3 polynomials, I felt entirely confident that I already computed them correctly, so I didn’t bother writing any more tests. If I were pairing with you and you had wanted to write more tests, I’d have written as many as it took to give you enough confidence to move on.&lt;/p&gt;
&lt;h1 id=&quot;the-thrilling-conclusion&quot;&gt;The Thrilling Conclusion&lt;/h1&gt;
&lt;p&gt;That’s it. Here’s &lt;a href=&quot;https://github.com/jbrains/evaluate-polynomial-of-one-variable/blob/main/lib/src/test/java/ca/jbrains/math/EvaluatePolynomialAtOnePointTest.java&quot;&gt;the final code&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.math;

import io.vavr.collection.List;
import net.jqwik.api.ForAll;
import net.jqwik.api.Property;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class EvaluatePolynomialAtOnePointTest {
    @Property
    void empty(@ForAll int point) {
        Assertions.assertEquals(0, Polynomial.of().at(point));
    }

    @Test
    void constant() {
        Assertions.assertEquals(5, Polynomial.of(5).at(2));
    }

    @Test
    void linearWithZeroIntercept() {
        Assertions.assertEquals(10, Polynomial.of(0, 5).at(2));
    }

    @Test
    void linearWithNonZeroIntercept() {
        Assertions.assertEquals(31, Polynomial.of(3, 4).at(7));
    }

    @Test
    void simplestQuadratic() {
        Assertions.assertEquals(45, Polynomial.of(0, 0, 5).at(3));
    }

    @Test
    void quadraticWithNonZeroLinearCoefficient() {
        Assertions.assertEquals(7 * 4 * 4 + 3 * 4, Polynomial.of(0, 3, 7).at(4));
    }

    @Test
    void quadraticWithNonZeroLinearCoefficientAndNonZeroConstant() {
        Assertions.assertEquals(7 * 4 * 4 + 3 * 4 + 9, Polynomial.of(9, 3, 7).at(4));
    }

    @Property
    void constantIsConstant(@ForAll int zerothPowerCoefficient, @ForAll int atPoint) {
        Assertions.assertEquals(zerothPowerCoefficient, Polynomial.of(zerothPowerCoefficient).at(atPoint));
    }

    private static class Polynomial {
        private final List&amp;lt;Integer&amp;gt; coefficients;

        public Polynomial(List&amp;lt;Integer&amp;gt; coefficients) {
            this.coefficients = coefficients;
        }

        public static Polynomial of(int... coefficients) {
            return new Polynomial(List.ofAll(coefficients));
        }

        public int at(int point) {
            if (coefficients.length() == 0) return 0;
            return coefficients.last() * pow(point, coefficients.length() - 1) + Polynomial.of(coefficients.init()).at(point);
        }

        // CONTRACT exponent &amp;gt;= 0
        private int pow(int base, int exponent) {
            int result = 1;
            while (exponent-- &amp;gt; 0) {
                result *= base;
            }
            return result;
        }

        private static Polynomial of(List&amp;lt;Integer&amp;gt; coefficients) {
            return new Polynomial(coefficients);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your comments and questions are welcome.&lt;/p&gt;
</description>
        <pubDate>Fri, 04 Feb 2022 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/polynomial-kata</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/polynomial-kata</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
        <category>Evolutionary Design</category>
        
        <category>Tutorials</category>
        
        <category>Removing Duplication Deftly</category>
        
      </item>
    
      <item>
        <title>Modularity and Performance</title>
        <description>&lt;p&gt;When I teach evolutionary design with TDD, I often encounter programmers who don’t like all these little classes and all these extra interfaces. (Or all these little higher-order functions, if you prefer. It’s the same problem.) They worry that it creates a serious performance problem: deeper call stacks, passing parameters around, that kind of thing. They see memory being unnecessarily allocated and freed, memory becoming fragmented, and garbage collection happening at the worst possible time.&lt;/p&gt;
&lt;p&gt;And yes, that can happen; however, this is very often &lt;em&gt;not&lt;/em&gt; where the performance problems lie in typical industrial-strength professional software development projects. More often&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, it’s like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A couple of days ago, we ran into performance problems in production, and by extracting the “code that grabs the data from infrastructure” up the call chain, we realized that there were lots of duplicate expensive database calls and other inefficient code that went through multiple databases to get something that could have been a single database query. –a slight paraphrase of a comment I received from one of my training course participants&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is what I see over and over again&lt;/strong&gt;. &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Removing duplication&lt;/a&gt; by &lt;a href=&quot;/series#dependency-inversion-principle-dip&quot;&gt;pulling details up the call stack&lt;/a&gt; makes it clear that we’re retrieving the same data from the database more than once. As the database access moves up the call stack towards the entry point, it collects into a single layer and often a single class/function/module, where removing the duplication becomes &lt;em&gt;easy&lt;/em&gt;. When we remove this duplication, two things happen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we create more, smaller classes and more interfaces&lt;/li&gt;
&lt;li&gt;we reduce the number of “trips” to expensive, external resources&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I discuss situations like this with my clients, most of the programmers feel comfortable accepting the smaller classes/functions/modules in exchange for reducing the number of trips across a network boundary or to the file system. Of course, they’d rather have the best of both worlds. Not only do I believe that they &lt;em&gt;can&lt;/em&gt;, but that as they refactor, they &lt;em&gt;will&lt;/em&gt;. &lt;strong&gt;They can’t not.&lt;/strong&gt;&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;a-simple-pattern&quot;&gt;A Simple Pattern&lt;/h2&gt;
&lt;p&gt;Using techniques such as routinely &lt;a href=&quot;/permalink/keep-dependency-injection-simple&quot;&gt;injecting dependencies&lt;/a&gt;, &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;pulling implementation details up the call stack&lt;/a&gt;, &lt;a href=&quot;/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;relentlessly driving irrelevant details out of the tests&lt;/a&gt;, we end up going through phases that look something like this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Break bigger modules (especially long methods/functions) into smaller modules that talk to each other through smaller/more-focused interfaces. This usually sacrifices some cohesion (not as much as you’d think) in exchange for looser coupling (and greater ease in testing). As a pleasant side-effect, this helps us notice the kinds of performance problems that my training course participant described to me. (“I’ve written these assertions before… Hey! Look! We’re doing the same thing in, like, 7 places!”)&lt;/li&gt;
&lt;li&gt;Take advantage of the looser coupling to move behavior around, generally in accordance with the &lt;a href=&quot;/series#dependency-inversion-principle-dip&quot;&gt;Dependency Inversion Principle&lt;/a&gt;. Among other things, this is when we &lt;em&gt;fix&lt;/em&gt; those performance problems. (“All this database access is now in one place. Let’s combine some queries.”)&lt;/li&gt;
&lt;li&gt;With the design arranged “better”, it becomes safer to combine modules/objects/functions into more-cohesive bundles. This makes the design easier to understand, but it also leads back (a little) in the direction of bigger modules/longer functions. As we add behavior, we often end up dumping implementation details into functions/methods where they don’t &lt;em&gt;quite&lt;/em&gt; belong. This happens because when we’re struggling to make some new thing work, we’re less concerned about how exactly to design it. It becomes easier just to “jam it in”, declare victory, then move on. The good news is that this leads us back into phase 1, where we can do this all again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;These three phases repeat forever. And this is natural.&lt;/strong&gt; This is &lt;em&gt;not&lt;/em&gt; a failure of design; instead, it’s a natural way for designs to evolve. That’s why we need some people on our project with a bias towards adding behavior and some with a bias towards refactoring: the first group reduces our over-investment in the design and the second group reduces our under-investment in the design. We don’t do much gold-plating and we delay becoming crushed under the weight of a Big Ball of Mud.&lt;/p&gt;
&lt;p&gt;We find balance.&lt;/p&gt;
&lt;h2 id=&quot;eventually&quot;&gt;Eventually…&lt;/h2&gt;
&lt;p&gt;And yes, over time, it might be the case that we find some performance problems related to too much indirection, allocating too much memory, passing too many arguments around. Imagine how well you’re likely doing if creating too many objects in memory is your most urgent performance problem!&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;If you work in one of those specialized, highly-constrained programming environments, where every kilobyte counts, then you might not want to keep reading. Even so, the few times that I’ve worked in those environments, I’ve still seen many “penny wise, pound foolish” design choices.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Programmers who refactor attentively, because they know how to do it &lt;strong&gt;and&lt;/strong&gt; have the opportunity to do it, will eventually get there. The complexity of and dysfunctions within the organization determine how far in the future “eventually” is.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sat, 08 Jan 2022 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/modularity-and-performance</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/modularity-and-performance</guid>
        
        
        <category>Simple Design</category>
        
        <category>Dependency Inversion Principle (DIP)</category>
        
        <category>Evolutionary Design</category>
        
      </item>
    
      <item>
        <title>Zero to nodejs on Linux</title>
        <description>&lt;p&gt;This is not a step-by-step guide, but more of an overview that can help you stitch together the detailed step-by-step guides out there.&lt;/p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;code&gt;nodejs&lt;/code&gt; and &lt;code&gt;npm&lt;/code&gt; packages from your distribution’s package manager. I’ll call this “System nodejs”. You’ll need &lt;code&gt;sudo&lt;/code&gt; to interact with it.&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;n&lt;/code&gt;, a node version manager, into System nodejs.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;n&lt;/code&gt; to install nodejs versions into your user space. For these versions, you don’t need &lt;code&gt;sudo&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;/h2&gt;
&lt;p&gt;I’m running Pop!_OS 21.04, which is essentially a flavor of Ubuntu, so this will look very Ubuntu-ish. If you don’t use &lt;code&gt;apt&lt;/code&gt; to install packages, then simply use your package manager.&lt;/p&gt;
&lt;p&gt;First, install Node with npm.&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;$ sudo apt-get install nodejs npm
$ node --version    # check that it&amp;#39;s installed&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, update your login scripts. I put this in my &lt;code&gt;.zshrc&lt;/code&gt; (well, eventually—I’ve refactored).&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;## NPM

# Put NPM packages in homedir
export NPM_PACKAGES=&amp;quot;$HOME/.npm-packages&amp;quot;

# Find user-installed node tools
export PATH=&amp;quot;$NPM_PACKAGES/bin:$PATH&amp;quot;

# Unset manpath so we can inherit from /etc/manpath via the `manpath` command
unset MANPATH  # delete if you already modified MANPATH elsewhere in your configuration
export MANPATH=&amp;quot;$NPM_PACKAGES/share/man:$(manpath)&amp;quot;

# Tell Node about these packages
export NODE_PATH=&amp;quot;$NPM_PACKAGES/lib/node_modules:$NODE_PATH&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install n, the annoyingly-named-but-delightful node version manager.&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;$ sudo npm install n --global
$ n --version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, update your login scripts again to know about n. I added this:&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;# Use n to manage node installations in place of NVM
# https://github.com/tj/n
export N_PREFIX=&amp;quot;$HOME/.n&amp;quot;
export PATH=&amp;quot;$N_PREFIX/bin:$PATH&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can install any version of nodejs without messing up System nodejs.&lt;/p&gt;
&lt;pre class=&quot;zsh&quot;&gt;&lt;code&gt;$ n latest    # switch to the latest version and installed it if it&amp;#39;s missing
$ n           # list the installed versions&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://itsfoss.com/install-nodejs-ubuntu/&quot;&gt;“How to Install Node.js and npm on Ubuntu Linux”&lt;/a&gt;. A generic guide that might be out of date by the time you read this. If so, then search the web.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.npmjs.com/package/n&quot;&gt;“&lt;code&gt;n&lt;/code&gt; – Interactively Manage Your Node.js Versions”&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/19451851/install-node-js-to-install-n-to-install-node-js&quot;&gt;“Install Node.js to install n to install Node.js?”&lt;/a&gt; A discussion on how to install n without installing System node. I didn’t try this, but if you feel adventurous, you might want to try it. Please add a comment to let me know how it went.&lt;/p&gt;
</description>
        <pubDate>Tue, 24 Aug 2021 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/zero-to-nodejs-on-linux</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/zero-to-nodejs-on-linux</guid>
        
        
        <category>The Little Things</category>
        
        <category>Tutorials</category>
        
      </item>
    
      <item>
        <title>Reading stdin and The Kotlin DSL for Gradle</title>
        <description>&lt;p&gt;I couldn’t figure this out myself, nor even find the appropriate Stack Overflow article on my own, so I’m writing this. I hope you find it and it alleviates your annoyed state.&lt;/p&gt;
&lt;p&gt;Is this you?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I want to read input from &lt;code&gt;stdin&lt;/code&gt; in my Java application.&lt;/li&gt;
&lt;li&gt;I want to run my application using &lt;code&gt;gradle run&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I’m learning the Kotlin build DSL for Gradle as a replacement for the Groovy build DSL, which I’m somewhat used to.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Great! That’s me, too.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;gradle run&lt;/code&gt; uses an empty input stream, so reading data from &lt;code&gt;stdin&lt;/code&gt; doesn’t block, waiting for the user to type on the console. The &lt;code&gt;application&lt;/code&gt; Gradle plugin provides a way to read from &lt;code&gt;System.in&lt;/code&gt;. I know how to do that with the Groovy build DSL:&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;// build.gradle
plugins {
    id &amp;#39;application&amp;#39;
}
[...]
// You need this!
run {
    standardInput = System.in
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, so good. What about the Kotlin build DSL? You see, &lt;code&gt;run()&lt;/code&gt; is a special function in Kotlin (or something—I don’t know yet), so this exact syntax doesn’t work.&lt;/p&gt;
&lt;p&gt;I tried reading tutorials, but my keywords kept finding tutorials on how to write Kotlin code to read from &lt;code&gt;stdin&lt;/code&gt;. I don’t want that.&lt;/p&gt;
&lt;p&gt;I tried reading tutorials, but my keywords kept finding tutorials on how to do this with the Groovy build DSL. I already know that.&lt;/p&gt;
&lt;p&gt;Finally, I did the only remaining thing: I tweeted that I couldn’t figure it out. Within 44 minutes, &lt;a href=&quot;https://twitter.com/devminded/status/1426671844942299136&quot;&gt;someone gave me an answer&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;an-answer&quot;&gt;An Answer&lt;/h2&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;// build.gradle.kts
plugins {
    application
}
[...]
tasks.withType&amp;lt;JavaExec&amp;gt;() {
    standardInput = System.`in`
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, &lt;code&gt;gradle run&lt;/code&gt; accepts input from the console. Excellent!&lt;/p&gt;
&lt;h2 id=&quot;why&quot;&gt;Why?!&lt;/h2&gt;
&lt;p&gt;The key points seem to be these ones:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Since &lt;code&gt;in&lt;/code&gt; is a keyword in Kotlin, we have to say &lt;code&gt;System.\`in\`&lt;/code&gt;, including the backtacks.&lt;/li&gt;
&lt;li&gt;Instead of adding properties to the &lt;code&gt;run&lt;/code&gt; task, we have to do something else, for reasons I don’t yet understand.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sadly, this solution involves setting the &lt;code&gt;standardInput&lt;/code&gt; property for &lt;em&gt;every&lt;/em&gt; task of type &lt;code&gt;JavaExec&lt;/code&gt; in the build. This seemed excessive, but once I saw this answer, it occurred to me what to try next—and the solution feels obvious, now that I know it.&lt;/p&gt;
&lt;h2 id=&quot;a-better-answer&quot;&gt;A Better Answer&lt;/h2&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;// build.gradle.kts
plugins {
    application
}
[...]
tasks.getByName(&amp;quot;run&amp;quot;, JavaExec::class) {
    standardInput = System.`in`
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, instead of setting this property for &lt;em&gt;all&lt;/em&gt; &lt;code&gt;JavaExec&lt;/code&gt; tasks, I set it for just the &lt;code&gt;run&lt;/code&gt; task. This still works!&lt;/p&gt;
&lt;p&gt;The key point &lt;em&gt;here&lt;/em&gt; seems to be specifying the &lt;em&gt;type&lt;/em&gt; of the task—the &lt;code&gt;JavaExec::class&lt;/code&gt; parameter. I infer that this downcasts the task to the correct concrete(-enough) type that supports the &lt;code&gt;standardInput&lt;/code&gt; writable property. Excellenter!&lt;/p&gt;
&lt;p&gt;This works for me, so I hope it works for you. If you can suggest improvements, then please comment below.&lt;/p&gt;
</description>
        <pubDate>Sat, 14 Aug 2021 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/stdin-gradle-kotlin-dsl</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/stdin-gradle-kotlin-dsl</guid>
        
        
        <category>The Little Things</category>
        
        <category>Tutorials</category>
        
      </item>
    
      <item>
        <title>Breaking Through That First TDD Block</title>
        <description>&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Change the code as usual&lt;br&gt;2. Write a test that only passes after the change&lt;br&gt;3. Revert to before 1&lt;br&gt;4. Type the test again (copy/paste is cheating &amp;amp; invalidates the warranty of the exercise)&lt;br&gt;5. Make it compile by changing the code&lt;br&gt;6. See it fail&lt;br&gt;7. Change the code to make it pass
&lt;/p&gt;
— Kent Beck (&lt;span class=&quot;citation&quot; data-cites=&quot;KentBeck&quot;&gt;@KentBeck&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/KentBeck/status/1421257650113634304?ref_src=twsrc%5Etfw&quot;&gt;July 30, 2021&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I literally did this for one afternoon (back in 1999, I think) and began to feel the difference almost immediately. I also happened to like that feeling, even though there were moments where it felt strange: think, think, think, give up, write the production code, I see…, write the test, run it, see it pass, Hmm…, undo all of it, count to 10 (no, really!), now write the test…. I practised this for a few weeks (my manager seemed not to notice any drop in my productivity!) and the block that Kent describes in his tweet was mostly gone. This helped me build the habit of writing the test first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The first change I noticed&lt;/strong&gt; was in step 4: when I wrote the test, I sometimes noticed that I could write a simpler, smaller, more-direct, or clearer (somehow) test. This was the first “Aha!” for me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The first &lt;em&gt;big&lt;/em&gt; change I noticed&lt;/strong&gt; was a change in how I thought about code. I thought more directly about inputs and desired outputs, rather than data structures and algorithms. I always managed to find suitable data structures and algorithms, anyway. I still do, even when I build them up impossibly incrementally.&lt;/p&gt;
&lt;p&gt;As I became more comfortable thinking about code in terms of inputs and desired outputs, &lt;strong&gt;I stopped seeing only classes and started seeing interfaces&lt;/strong&gt;. Previously, I hadn’t understood the value of interfaces at all, let alone how to use them effectively.&lt;/p&gt;
&lt;p&gt;Within a few months, I began deeply to understand what I didn’t like about programming: being forced to know &lt;em&gt;all these details&lt;/em&gt; about &lt;em&gt;that thing over there&lt;/em&gt; when I merely wanted to use it. Gradually, I saw this weakness in my own designs as well as in others’ designs.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/archive&quot;&gt;The rest is history&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can do it.&lt;/p&gt;
</description>
        <pubDate>Thu, 12 Aug 2021 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/breaking-through-that-first-tdd-block</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/breaking-through-that-first-tdd-block</guid>
        
        
        <category>Not Just Coding</category>
        
        <category>The Little Things</category>
        
      </item>
    
      <item>
        <title>Edit, Then Execute</title>
        <description>&lt;p&gt;I used to waste significant energy trying to edit shell commands at the shell command prompt. Yes, &lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Readline-vi-Mode.html&quot;&gt;I could use &lt;code&gt;vi&lt;/code&gt; mode on &lt;code&gt;readline&lt;/code&gt;&lt;/a&gt;, but that never quite gave me the same, rich experience. I found it helpful for minor edits, but when someone introduced me to the &lt;code&gt;edit-and-execute&lt;/code&gt; command, my entire relationship with command-line tools changed. Once I had the full power of my trusted text editor to compose and edit commands, I stopped valuing GUI clients as highly and I started valuing the scriptability of command-line UIs much more.&lt;/p&gt;
&lt;h2 id=&quot;quick-start&quot;&gt;Quick Start&lt;/h2&gt;
&lt;p&gt;If you run &lt;code&gt;bash&lt;/code&gt; or &lt;code&gt;zsh&lt;/code&gt; or something similar, then you can probably already do this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Search your history for a command. &lt;code&gt;$ history&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Make a note of the command number—I’m using 1892 as an arbitrary example—then edit that command. &lt;code&gt;$fc 1892&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This opens a text editor and lets you edit the command. When you save your changes and exit the editor, then the shell executes that edited command. &lt;strong&gt;Be careful!&lt;/strong&gt; Whatever you do, &lt;code&gt;fc&lt;/code&gt; will &lt;em&gt;automatically&lt;/em&gt; execute your command immediately after you exit the editor. If you saved your changes, then you’d execute the edited command; if you didn’t save your changes, then you’d execute the original command. More precisely, you’d execute whichever version of the command you most-recently saved before you exited the editor.&lt;/p&gt;
&lt;p&gt;Now that you’ve seen how &lt;code&gt;fc&lt;/code&gt; runs, you can see a weakness: you need to execute the original command at least once in order to be able to find it in your history in order to be able to edit it with &lt;code&gt;fc&lt;/code&gt;. What if you just want to change the command that’s currently drafted on your command prompt? What if you just pressed &lt;code&gt;up&lt;/code&gt; a few times to retrieve a recent command and you want to execute something similar, but not quite the same?&lt;/p&gt;
&lt;p&gt;Try this.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Draft a command on your prompt. Enter the command, but don’t execute it.&lt;/li&gt;
&lt;li&gt;Press these two keystrokes, one after the other: &lt;code&gt;ctrl+x&lt;/code&gt; then &lt;code&gt;ctrl+e&lt;/code&gt;. If you want, hold down the control key while you press first &lt;code&gt;x&lt;/code&gt;, then &lt;code&gt;e&lt;/code&gt;. If this does nothing, then try &lt;code&gt;esc&lt;/code&gt; followed by &lt;code&gt;v&lt;/code&gt; . (I’ll explain below.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This opens a text editor and lets you edit the command. When you save your changes and exit the editor, then you’ll see the edited command in your prompt, waiting for you to execute it. Nice!&lt;/p&gt;
&lt;h2 id=&quot;tweaks&quot;&gt;Tweaks&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Which editor does the &lt;code&gt;edit-and-execute&lt;/code&gt; command open?&lt;/strong&gt; You control this by setting the &lt;code&gt;EDITOR&lt;/code&gt; environment variable. &lt;a href=&quot;https://www.kakoune.org&quot;&gt;I have set this to &lt;code&gt;kak&lt;/code&gt;&lt;/a&gt;, because I love that editor. If you set nothing, you probably get nano.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you have already &lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Readline-vi-Mode.html&quot;&gt;set readline to &lt;code&gt;vi&lt;/code&gt; mode&lt;/a&gt;&lt;/strong&gt;, then you need to press &lt;code&gt;esc&lt;/code&gt; followed by &lt;code&gt;v&lt;/code&gt; . This is the vi command that corresponds to the emacs command &lt;code&gt;ctrl+x ctrl+e&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Nyquase/&quot;&gt;Moreover, &lt;strong&gt;if you install the &lt;code&gt;oh-my-zsh&lt;/code&gt; plugin &lt;code&gt;vi-mode&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;, then you need to press &lt;code&gt;esc&lt;/code&gt; followed by &lt;code&gt;v&lt;/code&gt; followed by &lt;code&gt;v&lt;/code&gt; again. This avoids collision with &lt;code&gt;esc v&lt;/code&gt;, which enters the familiar &lt;code&gt;vi&lt;/code&gt; Visual Mode at your command prompt. It took me about a day to get used to typing &lt;code&gt;esc v v&lt;/code&gt; to edit commands. Fortunately, I do it so often that training myself to remember the new keystrokes didn’t take long.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;Did you find this helpful? I like to teach microtechniques, because of their power to increase our capacity to think about bigger things than merely how to get things done using our fundamental tools. I intend to write more about microtechniques in the coming months, so if you’re interested, &lt;a href=&quot;https://blog.thecodewhisperer.com/series#microtechniques&quot;&gt;read other articles tagged with “microtechniques”&lt;/a&gt; and &lt;a href=&quot;/feed&quot;&gt;subscribe to the RSS feed&lt;/a&gt; of this blog.&lt;/p&gt;
&lt;/aside&gt;
</description>
        <pubDate>Fri, 16 Jul 2021 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/edit-then-execute</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/edit-then-execute</guid>
        
        
        <category>Microtechniques</category>
        
      </item>
    
      <item>
        <title>How I Wish I Had Some Unit Tests! An Example</title>
        <description>&lt;p&gt;Today I ran into an example of where I’d &lt;em&gt;really&lt;/em&gt; have liked to have some way to write a unit test. Let me clarify: by &lt;em&gt;unit test&lt;/em&gt;, I only mean &lt;em&gt;any test with a smaller scope than the entire system&lt;/em&gt;. I don’t want a microtest. I would even have felt satisfied with clearer, more up-to-date documentation, although perhaps I might not have trusted it.&lt;/p&gt;
&lt;h2 id=&quot;so-there-i-was&quot;&gt;So, There I Was…&lt;/h2&gt;
&lt;p&gt;Today, I saw this task pop up in Todoist:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Write a &lt;a href=&quot;https://functions.netlify.com/&quot;&gt;Netlify Function&lt;/a&gt; to schedule removing a participant from &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;The jbrains Experience&lt;/a&gt; in &lt;a href=&quot;https://online-training.jbrains.ca&quot;&gt;Teachable&lt;/a&gt; when they cancel their subscription in &lt;a href=&quot;https://thrivecart.com&quot;&gt;Thrivecart&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Before I do that, I try building an automation with Integrately, just to see how far I can get. You never know. In doing this, I notice something new and potentially helpful. In the payload of the sample “subscription canceled” event from Thrivecart, I notice a property called “Billing period end” with a timestamp. This might be what I’m looking for.&lt;/p&gt;
&lt;p&gt;Unfortunately, I’ve seen this film before. I couldn’t be sure that “Billing period end” means “the end of the current billing period” as opposed to “the end of the first billing period”. I’d &lt;em&gt;like&lt;/em&gt; to trust their name, but I’d rather &lt;em&gt;verify&lt;/em&gt; that Thrivecart and I stand on the same page.&lt;/p&gt;
&lt;p&gt;I went looking for details in their documentation and didn’t find it, so I did the next-best thing: I devised a Learning Test.&lt;/p&gt;
&lt;h2 id=&quot;wait-how-do-i-test-this&quot;&gt;Wait… How Do I Test This?!&lt;/h2&gt;
&lt;p&gt;I mean… I can go to &lt;a href=&quot;https://webhook.site&quot; class=&quot;uri&quot;&gt;https://webhook.site&lt;/a&gt; and subscribe to Thrivecart for “Subscription Canceled” events, then “buy” a subscription for a Product in Test mode. Great! I tried that and didn’t receive any events. For Products in Test mode, Thrivecart does not seem to generate webhook events. I inferred that I need to buy a “real” Live subscription. No problem! I create a subscription product whose price is $0.&lt;/p&gt;
&lt;p&gt;Well… &lt;em&gt;almost&lt;/em&gt;. Thrivecart doesn’t let me create a subscription product with a cost of $0. The best I can do is a subscription product whose recurring price if $1, but whose first-month price is $0. &lt;strong&gt;I wish I could run a unit test, because then I wouldn’t care about the price of the subscription product&lt;/strong&gt;. Alternatively, I could give myself a 100% off coupon, but that adds a step to an already complicated manual test, so I accept this limitation and create a subscription product at the price of $0 for the first month, then $1/month thereafter. I find this mildly annoying, but I can deal with it.&lt;/p&gt;
&lt;p&gt;I use my Webhook URL to subscribe to Thrivecart webhook events. I “buy” the “real” $0/$1 subscription product using PayPal, so that I can easily confirm when I will have canceled the $1 recurring payment. I then cancel the subscription, including the PayPal recurring payment. After I do all this, which requires about 10 steps in total, I look at the incoming event in Webhook and I see something promising:&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &amp;quot;event&amp;quot;: &amp;quot;order.subscription_cancelled&amp;quot;,
  &amp;quot;mode&amp;quot;: &amp;quot;live&amp;quot;,
  &amp;quot;mode_int&amp;quot;: &amp;quot;2&amp;quot;,
[...]  
  &amp;quot;base_product&amp;quot;: &amp;quot;10&amp;quot;,
  &amp;quot;base_product_name&amp;quot;: &amp;quot;Test subscription product&amp;quot;,
  &amp;quot;base_product_label&amp;quot;: &amp;quot;Test subscription product&amp;quot;,
[...]    
  &amp;quot;subscription&amp;quot;: {
    &amp;quot;type&amp;quot;: &amp;quot;product&amp;quot;,
    &amp;quot;id&amp;quot;: &amp;quot;10&amp;quot;,
    &amp;quot;product_id&amp;quot;: &amp;quot;10&amp;quot;,
    &amp;quot;name&amp;quot;: &amp;quot;Test subscription product&amp;quot;,
    &amp;quot;label&amp;quot;: &amp;quot;Test subscription product&amp;quot;,
[...]
    &amp;quot;frequency&amp;quot;: &amp;quot;month&amp;quot;,
    &amp;quot;frequency_days&amp;quot;: &amp;quot;30&amp;quot;,
    &amp;quot;remaining_rebills&amp;quot;: &amp;quot;null&amp;quot;,
    &amp;quot;billing_period_end&amp;quot;: &amp;quot;1628712591&amp;quot;,
    &amp;quot;billing_period_end_iso8601&amp;quot;: &amp;quot;2021-08-11T20:09:51+00:00&amp;quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The salient part is &lt;code&gt;billing_period_end&lt;/code&gt; (and its human-readable companion &lt;code&gt;billing_period_end_iso8601&lt;/code&gt;). The value is what I would expect: 1 month (to the second!) after the purchase instant. Well… that’s &lt;em&gt;great&lt;/em&gt;, but it doesn’t help me confirm that I can safely interpret this “billing period end” value the way I expect to. In order to do that, I’d need to cancel a subscription that’s more than 1 month old.&lt;/p&gt;
&lt;p&gt;And &lt;em&gt;that’s&lt;/em&gt; where &lt;strong&gt;I wish I had some unit tests&lt;/strong&gt;! I wish I had a sandbox environment in which I could retroactively create a subscription from 32 days ago. If I had access to the Domain code, suitably decoupled from the Technology Integration code, then I could write a single unit test to answer my question. &lt;strong&gt;But I can’t&lt;/strong&gt;. And that makes me just a little bit sad.&lt;/p&gt;
&lt;h2 id=&quot;so-what&quot;&gt;So What?!&lt;/h2&gt;
&lt;p&gt;This situation illustrates the down side of assuming that “sensible usage patterns” are the only usage patterns that need to be available to your customers. In production, of course, we probably don’t want to let customers retroactively create subscriptions that started in the past—&lt;em&gt;or do we&lt;/em&gt;? I could imagine wanting this feature in order to migrate subscriptions from a legacy platform into Thrivecart. Even if you, the Director of this Product, want to restrict users from doing this in production, consider making this behavior available in a &lt;em&gt;sandbox environment&lt;/em&gt;, in which your customers can play whatever “what if?” game they need to play in order to test their stuff. Your sandbox environment benefits from not being bound by the same constraints as the production system.&lt;/p&gt;
&lt;p&gt;The same is true of your code. Let the programmers arrange objects, modules, or values into any graph that one could possibly need and that respects the business rules of the system, &lt;em&gt;even if&lt;/em&gt; you want to stop end users from doing those things. Let them create a new Subscription that “started” 6 months ago. Let them create a Shopper that already has a Purchase History with 23 Purchases in it without needing to run the purchasing workflow 23 times. Not only does this help them write clearer tests, but you might get certain features “free of charge”, like pause/resume or import/export.&lt;/p&gt;
&lt;p&gt;Either way… please keep your published documentation up to date as APIs change. And when one of your customers asks you to notify them when you add a feature in the future, then please notify them when you add that feature. If you don’t have a &lt;em&gt;trusted system&lt;/em&gt; to help you do that, then maybe you need to &lt;a href=&quot;https://blog.jbrains.ca/permalink/getting-started-with-getting-things-done&quot;&gt;get started with Getting Things Done&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;
&lt;p&gt;Thrivecart confirmed the meaning of this “billing period end” attribute by telling me directly. I appreciate them for doing that. I asked them to update their documentation. I hope they find the time to do that. Overall, &lt;strong&gt;Thrivecart has delighted me as a customer&lt;/strong&gt; and I recommend them to anyone who needs to sell products and services online. (Isn’t that everyone now?)&lt;/p&gt;
&lt;h2 id=&quot;epilogue-to-the-epilogue&quot;&gt;Epilogue to the Epilogue&lt;/h2&gt;
&lt;p&gt;One month after writing this article, I got my first real-life customer who canceled who had been subscribing for longer than one month, and for whom I received confirmation that “billing period end” means what I expected and hoped it would mean.&lt;/p&gt;
&lt;p&gt;That’s a long feedback loop.&lt;/p&gt;
</description>
        <pubDate>Sun, 11 Jul 2021 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-i-wish-i-had-some-unit-tests-an-example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-i-wish-i-had-some-unit-tests-an-example</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>How to Write Tests For Framework Extensions?</title>
        <description>&lt;h1 id=&quot;a-reader-question&quot;&gt;A Reader Question&lt;/h1&gt;
&lt;p&gt;Recently I came across attempts to verify framework-based behavior. This is what I saw:&lt;/p&gt;
&lt;p&gt;We introduce a framework like JPA Query Builder, RestEasy, or Spark. Then we get two kinds of code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the code which uses a sequence of framework-specific calls (like run-time JPA query building)&lt;/li&gt;
&lt;li&gt;the code which uses annotations to configure system behavior (like JAX-RS annotations for ReST paths)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now I start seeing two kinds of unit tests.&lt;/p&gt;
&lt;p&gt;The first kind relates to verifying framework calls: it verifies the code makes ‘expected’ calls to the framework (like building JPA query via multiple API calls or calls Spark API to configure processing or ReST requests). This is a unit test, since the framework API is mocked, but then to me it makes little-to-no sense. We only care about some final call to the framework (with an object built via API calls) or we expect the framework to handle incoming requests correctly because we configured it properly in run-time. An alternative to this kind of test may be an integrated test, where we run our method in a live environment where the framework is instantiated inside its runtime container (within which our code is run as well). As an example, a JPA query builder-based code is run in some kind of JPA-enabled container to make sure that database calls have expected results.&lt;/p&gt;
&lt;p&gt;In fact, the second kind of tests are exactly those integrated tests, which verify that framework is configured correctly. For instance, an HTTP-enabled container gets initialized and we run just enough of our code (with the latter annotated with JAX-RS annotations and may be even having some dependencies mocked) to make it possible to send live HTTP requests to the container and verify some kind of expected outcomes.&lt;/p&gt;
&lt;p&gt;So, the question is can we safely say, that given visual inspection (or something) the integrated checks are not really needed for annotation-based code? What do we really need to test here?&lt;/p&gt;
&lt;p&gt;This still leaves the question about the meaninglessness of verifying run-time framework configuration against API mocks.&lt;/p&gt;
&lt;p&gt;May be those kinds of integrated checks are unavoidable?&lt;/p&gt;
&lt;p&gt;Also, as a dessert a different question.&lt;/p&gt;
&lt;p&gt;Is there a guide on mock boundaries? Basically, the question was shouldn’t we mock everything including language API libraries (like &lt;code&gt;Arrays.length&lt;/code&gt;)? If not, then how far should we push the envelope of mocking? Is there any reasoning-based guidance (not really an inflexible dogma) about when to stop mocking?&lt;/p&gt;
&lt;h1 id=&quot;discussion&quot;&gt;Discussion&lt;/h1&gt;
&lt;p&gt;I don’t feel certain that I know your intention when you say “unit test”. I avoid using this term because many people disagree on what is a “unit”, and then they spend a lot of time arguing about this question. I believe that they waste their time and energy when they do this. I only mention this for two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I’m explaining why I use different terms from “unit test”, in case this confused you.&lt;/li&gt;
&lt;li&gt;I’m trying to encourage more people to stop using this term when some other, more-specific, clearer term is available.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even if this doesn’t inform the rest of my answer, I wanted to mention it, in order to avoid confusion in the future.&lt;/p&gt;
&lt;h2 id=&quot;consider-the-goal-of-each-test&quot;&gt;Consider the Goal of Each Test&lt;/h2&gt;
&lt;p&gt;Regarding your first kind of test, I think I notice a common risk: writing one test to check two parts of the system. In particular, I notice that programmers confuse themselves by trying to use a single test to check both their understanding of how the framework works and the behavior that they want to deploy into that framework. I find that my results improve when I check each kind of behavior in its own test.&lt;/p&gt;
&lt;p&gt;You might have experienced this problem before: you’re writing code in an unfamiliar framework, it doesn’t work, and you don’t know whether the problem lies in your code or their documentation. Everyone reacts differently: some people assume that that their code is wrong, some assume that the framework documentation is wrong, and other people stubbornly refuse to guess. Almost everyone wastes a lot of energy, feeling some kind of anxiety from the uncertainty. &lt;strong&gt;I avoid this problem by clarifying the intent of each test.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I notice this risk in my code, I stop and write tests to explore my assumptions about how their framework works. Since I’m exploring their framework and not my code, I choose examples based on how I think the framework behaves, rather than based on the application I’m trying to build. This leads me to write classical Learning Tests for their framework, which act as classical acceptance tests for their framework. These aren’t even tests for my application! They act instead as enhanced documentation for the framework—the kind of documentation that I wish the framework authors had written.&lt;/p&gt;
&lt;p&gt;When I do this, it becomes easier to see the boundary between their framework and my code. This makes it even easier to write tests for my code that focuses on my code rather than on some fuzzy combination of my code and their framework. When I do this, it becomes easier to identify the source of problems when tests fail. Even better, when I try to write one of those tests near the boundary between their framework and my code, it becomes clear quite soon that &lt;strong&gt;I don’t understand something well enough even to express the assertions&lt;/strong&gt;. This leads me to focus on the part of the code that I need to understand better. Sometimes it’s their framework and sometimes it’s my transaction script or domain code or whatever.&lt;/p&gt;
&lt;p&gt;When I separate these kinds of behavior from each other, then I avoid that feeling of confusion: &lt;em&gt;Why am I checking a framework function call when I’m interested in how my controller interacts with my domain model?&lt;/em&gt; or &lt;em&gt;Why am I stubbing this framework function when I really care that my controller invokes the right update in my model?&lt;/em&gt; These questions signal me that I’m writing integrated tests with unclear boundaries, unclear focus, and unclear intentions. When I take a moment to isolate these kinds of behavior from each other, the intent of the tests becomes clearer and this kind of confusion disappears.&lt;/p&gt;
&lt;p&gt;If you want to verify that you know how to configure the framework correctly, then &lt;em&gt;don’t use your application code to do that&lt;/em&gt;. Instead, create a tiny project, integrate the framework, then write tests (integrated or isolated, as you need them) that help you feel confident that you understand how to configure the framework. These tests will help you feel confident that you understand the effects of your configuration choices, but they won’t necessarily help you feel confident that &lt;em&gt;this&lt;/em&gt; application requires &lt;em&gt;that&lt;/em&gt; set of choices. You might need to write some system tests (integrated tests) to get that kind of confidence, but you probably don’t need to write a large number of them, and you almost certainly don’t need to write a new set of them for each new part of your application as you build it. Quite often, configuration choices affect system-level properties that go beyond computing the right answer, into things like throughput, response time, and memory usage. If I run automated tests for these, I tend to write system tests, such as load tests; otherwise, I monitor the running application in production to measure its performance.&lt;/p&gt;
&lt;h2 id=&quot;integrated-tests-or-isolated-tests&quot;&gt;Integrated Tests Or Isolated Tests?&lt;/h2&gt;
&lt;p&gt;When integrating with the framework, I typically write integrated tests to explore their framework, and then write microtests after I’ve explored “enough” and feel confident that I understand &lt;strong&gt;the contract of the framework extension point&lt;/strong&gt;. I end up writing more integrated tests both early in the project and whenever I need to explore some part of the framework I hadn’t yet used. As I use the same part of the framework more often, I don’t need integrated tests for that and I trust my contract tests—my assumptions about how the framework behaves—more and more.&lt;/p&gt;
&lt;p&gt;Annotations (in Java, or attributes in .NET) tend to force me to write more integrated tests. I accept that. I hope that I end up using a small number of well-defined, well-tested, well-documented annotations. If not, then I end up spending some time and energy writing the tests and documentation that I wish the annotation authors had provided. I usually expect the cost of this work to be higher early in the project and to drop to near-zero relatively soon after that. Eventually the annotations become just another kind of code that we know deeply and trust, so we focus our testing efforts in other parts of the system.&lt;/p&gt;
&lt;p&gt;As for whether manual inspection suffices, you have to decide that for yourself. Remember: &lt;strong&gt;test until fear is transformed into boredom&lt;/strong&gt;. If you feel fear, then write more tests; and as you feel more confident, trust your visual inspection more. This becomes a self-regulating system as long as you follow one simple rule: &lt;strong&gt;when something blows up in your face, then write more tests for that part&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;a-flexible-not-dogmatic-approach-to-using-test-doubles&quot;&gt;A Flexible (Not Dogmatic) Approach To Using Test Doubles&lt;/h2&gt;
&lt;p&gt;My advice on this has not changed much over the years. I wrote something about this in 2010, based on advice I’d been following and giving for years. You can read the details in &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/when-is-it-safe-to-introduce-test-doubles&quot;&gt;“When Is It Safe To Introduce Test Doubles?”&lt;/a&gt;. Please remember that these are general rules, not to follow exactly, but to follow unless you know exactly why you’re choosing not to follow them. In addition to this advice, I recommend that you “don’t mock types that you don’t own”, generally speaking. You can read more about that starting at &lt;a href=&quot;https://davesquared.net/2011/04/dont-mock-types-you-dont-own.html&quot;&gt;“Don’t Mock Types You Don’t Own”&lt;/a&gt; and continuing to the classic &lt;a href=&quot;https://jmock.org/oopsla2004.pdf&quot;&gt;“Mock Roles, Not Types”&lt;/a&gt;. This last article, although from 2004, continues to serve me well. I can also recommend Matteo Vaccari’s &lt;a href=&quot;https://medium.com/@xpmatteo/how-i-learned-to-love-mocks-1-fb341b71328&quot;&gt;“How I Learned to Love Mocks”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Beyond these guidelines, however, lies the larger principle: &lt;strong&gt;use test doubles when you want to check one bit of behavior without knowing the details of how to implement another bit of behavior nearby&lt;/strong&gt;. When I find myself saying, “I just want &lt;em&gt;a thing&lt;/em&gt; to do &lt;em&gt;this&lt;/em&gt;”, then I interpret to mean that I want an &lt;em&gt;abstraction&lt;/em&gt; to do &lt;em&gt;“this”&lt;/em&gt;, and in those situations, I generally want to use a test double to simulate that behavior. I tend to follow this guideline and then look for evidence that it’s hurting me, and it hurts me only very rarely. Even when it hurts me, I try to interpret that to mean that I’m missing a useful abstraction, and when I look for that abstraction, I usually find it and it usually helps me. (I don’t sit there for days until I find the abstraction; sometimes it comes to me suddenly while I’m doing something else entirely.)&lt;/p&gt;
&lt;p&gt;I encourage you to follow the guidelines until you feel comfortable enough to use this larger principle directly.&lt;/p&gt;
&lt;h1 id=&quot;do-you-have-questions&quot;&gt;Do You Have Questions?&lt;/h1&gt;
&lt;p&gt;If you would benefit from mentoring like this, then consider becoming a member of &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;The jbrains Experience&lt;/a&gt;. Members get direct answers to their questions, commission new articles on topics that matter to them, and participate in &lt;a href=&quot;https://office-hours.jbrains.ca&quot;&gt;Office Hours&lt;/a&gt; several times per month.&lt;/p&gt;
&lt;p&gt;If membership isn’t for you, don’t worry: &lt;a href=&quot;https://ask.jbrains.ca&quot;&gt;you can still ask your question&lt;/a&gt;, but I can’t give you any service level guarantees about when you’d receive an answer.&lt;/p&gt;
</description>
        <pubDate>Sun, 14 Mar 2021 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-to-write-tests-for-framework-extensions</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-to-write-tests-for-framework-extensions</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Abstract Test Cases, 20 Years Later</title>
        <description>&lt;p&gt;While writing something else entirely, I stumbled upon one of my earliest contributions to the evolutionary design/TDD community. I called them &lt;em&gt;abstract test cases&lt;/em&gt; at the time, but today we know them as &lt;em&gt;contract tests&lt;/em&gt;. Has much changed in the 20 years since I first wrote about this in public? &lt;a href=&quot;https://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines&quot;&gt;No.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use &lt;em&gt;contract tests&lt;/em&gt; to &lt;strong&gt;gain confidence that a module implements its declared protocol&lt;/strong&gt;. If you prefer OOP terms, i use contract tests to gain confidence that a &lt;em&gt;class&lt;/em&gt; implements its declared &lt;em&gt;interface&lt;/em&gt;. The &lt;strong&gt;Liskov Substitution Principle&lt;/strong&gt; guides me here: we must be able to freely replace a supplier module with another supplier that claims to act as the same &lt;em&gt;type&lt;/em&gt;. I prefer, therefore, to let clients depend on types (roles, interfaces, however you like to think of them) rather than classes (implementations, details). This restates the &lt;strong&gt;Dependency Inversion Principle&lt;/strong&gt;.&lt;/p&gt;
&lt;p class=&quot;aside&quot;&gt;
I’ve been claiming for years now that we can reduce SOLID to LD and lose nothing of real value. (S, O, and I follow from L and D. I leave the exercise to whoever has the energy to write that book before I get around to it.)
&lt;/p&gt;
&lt;p&gt;When I write contract tests, &lt;strong&gt;I define the contract&lt;/strong&gt; of the module under test. The suite of tests &lt;em&gt;defines&lt;/em&gt; the &lt;em&gt;contract&lt;/em&gt;, which is the behavior that clients can reasonably rely on. It defines the &lt;em&gt;type&lt;/em&gt; that the module implements, even when I don’t explicitly extract an interface for it, as I might in Java. The contract tests don’t merely check the behavior of the module under test, but &lt;strong&gt;they also document the contract of that module by example&lt;/strong&gt;. When you see memes joking about “2 unit tests, 0 integration tests [sic]”, I replace that in my mind with “2 implementation details tests, 0 contract tests”. Many programmers still make the mistake of writing only collaboration tests, but no contract tests, which results in integration errors, leading many of them to fall into the &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests scam&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;two-styles-both-work&quot;&gt;Two Styles; Both Work&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;When I’m writing code supplier-first&lt;/strong&gt; (also sometimes called “bottom-up”), I test-drive the implementation, then identify the contract, then finally extract contract tests for it. I demonstrate this technique in &lt;a href=&quot;https://tdd.training&quot;&gt;The World’s Best Intro to TDD: Level 1&lt;/a&gt;. (Search the course details for “Contract Tests”.) In this situation, I’m generally focusing on integrating something with an Expensive External Resource (like an HTTP API, a database, or a file system), so I tend to become absorbed by getting the thing to work at all. Once something works, I can step back, breathe deeply, and think about the interface (and contract) that it will expose to the rest of the system. In this flow, it feels natural to me to &lt;strong&gt;let the supplier stabilize before trying to extract contract tests&lt;/strong&gt; and start advertising a contract to potential clients.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When I’m writing code client-first&lt;/strong&gt;—usually with test doubles—I use the collaboration tests to define the contract of its intended suppliers by example. As I write more collaboration tests, I refine my understanding of what this object needs from its collaborators. When I write a test, I usually say to myself, “I need a &lt;em&gt;thing&lt;/em&gt; that does X”, and when I say “thing”, that means “type” (“role”, “interface”, whatever you prefer). &lt;strong&gt;The stubs and expectations that I write for this &lt;em&gt;type&lt;/em&gt; gradually form the contract of the type.&lt;/strong&gt; Eventually the client’s behavior stabilizes enough to move on, at which point the collection of stubs and expectations constrain and define the contract that I’ve invented. (Not perfectly, but enough to understand.) I can translate these into contract tests and they become the first draft of the test list for building a production implementation. I demonstrate this technique as well in &lt;a href=&quot;https://tdd.training&quot;&gt;The World’s Best Intro to TDD: Level 1&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;a-contract-is-a-negotiation&quot;&gt;A Contract Is a Negotiation&lt;/h2&gt;
&lt;p&gt;Whichever approach I take—client-first or supplier-first—I treat these new contracts as &lt;em&gt;drafts&lt;/em&gt;, subject to revision. This seems obvious, but I routinely watch programmers treat existing contracts like laws and assume that they have no authority to change them. When I ask the client to try to use the supplier’s &lt;em&gt;type&lt;/em&gt; in a collaboration test, &lt;strong&gt;I learn about the API from the client’s point of view&lt;/strong&gt;. When I try to implement the supplier, I learn which constraints of the implementation might create obstacles to my ideal API. At this point I often learn that I need to replace fine-grained interactions with coarser-grained ones (or the reverse). I don’t even need to integrate the client with the supplier &lt;em&gt;implementation&lt;/em&gt; yet. &lt;strong&gt;The combination of collaboration and contract tests gives me enough confidence that the two will work together when I integrate them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I tend to limit integrated tests to the roles of checking performance, demonstrating progress to a Customer, integrating with the Horrible Outside World, and &lt;strong&gt;blunder checking my contracts&lt;/strong&gt;. Smoke tests usually suffice to find out whether my understanding of the relevant contracts is far off from reality. If the Customer wanted exhaustive integrated tests—and I don’t remember the last time they cared—I’d encourage them to engage dedicated testers to do that, then I’d work with those testers to compare notes and refine the contract. They could keep the integrated tests and, as they found problems, I’d extract missing or misaligned collaboration and contract tests to augment my programmer test suite. &lt;strong&gt;All integration problems come down to either a misunderstanding or disagreement about the contract of a type.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-trouble-with-contract-tests-semantic-drift&quot;&gt;The Trouble With Contract Tests: Semantic Drift&lt;/h2&gt;
&lt;p&gt;Finally, we have the classic question: &lt;em&gt;How do I keep my collaboration tests and contract tests in agreement with each other?&lt;/em&gt; If we experience semantic drift between them, then we risk the situation where our microtests pass 100% and we nevertheless have a relatively obvious integration defect. (Why are you returning &lt;code&gt;null&lt;/code&gt;?! You’re supposed to raise an error!!) That threatens to lead us back into the arms of the &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests scam&lt;/a&gt;. &lt;strong&gt;Even after 20 years, I still don’t have a better answer than to rely on the human to pay attention and check.&lt;/strong&gt; Various projects have tried to automate this, but I’ve not yet seen one publish results from an industrial-strength programming project using their system. Instead, I rely on these two rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;stub&lt;/em&gt; in a &lt;em&gt;collaboration test&lt;/em&gt; corresponds to an &lt;em&gt;expected result&lt;/em&gt; in a &lt;em&gt;contract test&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;An &lt;em&gt;expectation&lt;/em&gt; in a &lt;em&gt;collaboration test&lt;/em&gt; corresponds to an &lt;em&gt;action&lt;/em&gt; in a &lt;em&gt;contract test&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first of these rules says “If the Supplier might return &lt;code&gt;12&lt;/code&gt;, then check the Client to see how it reacts to the answer &lt;code&gt;12&lt;/code&gt;”. The second of these rules says “If the Client might tell the Supplier to &lt;code&gt;foo()&lt;/code&gt;, then check the Supplier to see what &lt;code&gt;foo()&lt;/code&gt; does”. When I write a collaboration test, I know which contract tests I need to write next. If I write a contract test, then I know which collaboration tests to look at in order to check for agreement. Without sophisticated static analysis tools, I don’t know how to automate this. Worse, thanks to dynamic metaprogramming, it seems in principle impossible to trust these tests enough to find them of value. &lt;strong&gt;I merely follow these two rules, attend to the tests, and try to be less wrong today than I was yesterday.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;one-significant-change&quot;&gt;One Significant Change&lt;/h2&gt;
&lt;p&gt;I can identify one significant change to my &lt;em&gt;contract tests&lt;/em&gt; practice since we had these discussions 20 years ago: someone showed me a second way to structure contract tests, which I’ve adopted as a second option.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;traditional&lt;/em&gt; approach involves &lt;strong&gt;extracting an abstract superclass&lt;/strong&gt; for the test case class, pulling up the tests as &lt;em&gt;template methods&lt;/em&gt; while leaving behind the implementation details of the &lt;em&gt;primitive operations&lt;/em&gt;. The concrete test subclass inherits the tests from the abstract test superclass. The test runner runs only the concrete test subclass. The abstract test superclass acts as an &lt;em&gt;abstract factory&lt;/em&gt; for instances of the &lt;em&gt;type&lt;/em&gt; being tested and the concrete test subclass implements that factory to provide instances of the implementation being tested in various required states. When we want to add an implementation, we use the abstract test superclass as a template for all the contract tests we need to make pass.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;newer&lt;/em&gt; approach &lt;strong&gt;favors composition over inheritance&lt;/strong&gt;. It involves writing a concrete class that provides the tests, but &lt;strong&gt;whose fixture includes an abstract factory object that creates instances of the objects to test&lt;/strong&gt;, in the style of the &lt;a href=&quot;https://www.martinfowler.com/bliki/ObjectMother.html&quot;&gt;Object Mother pattern&lt;/a&gt;. We add tests by implementing the abstract factory for our new Supplier implementation, then adding an instance of that factory to the list of factories that the tests run against, using the &lt;a href=&quot;https://www.baeldung.com/parameterized-tests-junit-5&quot;&gt;Parameterized Test Case pattern&lt;/a&gt;. This approach works especially well using property-based testing tools &lt;em&gt;and&lt;/em&gt; has the advantage of not needing to inherit implementation. In languages like Java, we can collect all the tests for a class in one place, even if that class implements more than one type, each with its own isolated set of contract tests.&lt;/p&gt;
&lt;h2 id=&quot;the-classics-never-go-out-of-style&quot;&gt;The Classics Never Go Out Of Style&lt;/h2&gt;
&lt;p&gt;I’ve changed how I think about and talk about contract tests over the past 20 years, but &lt;strong&gt;the concepts and goals haven’t changed at all&lt;/strong&gt;. I still favor contract tests over integrated tests. I still think in terms of contract tests, even f I don’t extract literal abstract test cases from the tests for the Supplier implementation. I still fix defects by working gradually from a failing integrated test to some number of missing or incorrect collaboration and contract tests. (The Saff Squeeze helps me here.)&lt;/p&gt;
&lt;p&gt;Many programmers still find this overkill, even though &lt;strong&gt;they’ll happily copy and paste excessive setup code to 20 more integrated tests every week&lt;/strong&gt;. They still fool themselves into believing that they can successfully use third-party libraries and frameworks without attending to the details of the contracts of those dependencies. They continue to struggle with remembering how &lt;em&gt;that thing&lt;/em&gt; worked, because they didn’t write it down in a &lt;em&gt;learning test&lt;/em&gt; nor in a &lt;em&gt;contract test&lt;/em&gt; when they originally wrote that part of the integration with the Horrible Outside World. They continue to be caught flat-footed when someone on another team publishes a breaking change, causing a defect, raising an alarm, and &lt;strong&gt;violently plunging the group into yet more unplanned work&lt;/strong&gt;. I frequently encounter clients who fail to heed my warnings as over-engineering, but then complain about problems that these techniques address. I understand: it’s not easy to see some traps until you become caught in them.&lt;/p&gt;
&lt;p&gt;No worries. I’ll sit here in the corner, writing my contract tests. In 20 years, they haven’t let me down yet. I’ve left an empty seat for you when you’d like to join me. No judgment, I promise. When you’re ready, I’m ready.&lt;/p&gt;
&lt;details class=&quot;external-excerpt&quot;&gt;
&lt;summary&gt;
Click here to read the original “Abstract Test Cases” discussion, rescued from &lt;a href=&quot;https://wiki.c2.com/?AbstractTestCases&quot;&gt;Ward Cunningham’s WikiWikiWeb&lt;/a&gt;
&lt;/summary&gt;
&lt;section class=&quot;details-content&quot;&gt;
&lt;p class=&quot;note&quot;&gt;
This discussion took place mostly in the period 1999-2001, but with some additions as late as 2009.
&lt;/p&gt;
&lt;h2 id=&quot;j.-b.-rainsberger&quot;&gt;J. B. Rainsberger&lt;/h2&gt;
&lt;p&gt;I have begun calling these “Contract Tests”, because they describe the contract that all implementors or inheritors must respect. Violating those contracts violates the Liskov Substitution Principle, and we all know that’s just bad.&lt;/p&gt;
&lt;p&gt;I use Contract Tests very aggressively to support Isolation Testing (testing objects in total isolation from the implementation details of their collaborators). I tried to write a good example, but it wasn’t good. I’ll try again later. The expected results in the Contract Tests for interface X become the assumptions I use when testing class Y that uses interface X. This is especially useful in one general area: business logic and the database.&lt;/p&gt;
&lt;p&gt;I generally introduce a Repository interface to hide the database. I test-drive the database-aware implementation, but pull up the general “push and pull data” tests up as Contract Tests for Repository. These Contract Tests now describe the assumptions I’m allowed to use when I introduce fake or mock Repository objects into business logic tests.&lt;/p&gt;
&lt;p&gt;Dale Emery once wrote that when he uses only Isolation Tests he sees disagreements between what objects do and what their clients/users expect them to do. Good Contract Tests help me avoid this problem so much that I rarely use Integration Tests or end-to-end tests for myself any more. I let my Customer write them, but I generally don’t care.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;An Abstract Test Case is a Test Case for an Abstract Class that ensures that concrete implementations of the abstract class behave as expected.&lt;/p&gt;
&lt;p&gt;The Abstract Test Case will have abstract methods to enable it to obtain concrete subclasses of the Abstract class under test, to obtain appropriate arguments for tests and expected results.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger put it well when he said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This kind of test case ensures that concrete classes do not violate the contracts of their superclasses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A suite of Abstract Test Cases are available here: &lt;a href=&quot;https://sourceforge.net/projects/junit-addons&quot; class=&quot;uri&quot;&gt;https://sourceforge.net/projects/junit-addons&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;channing-walton&quot;&gt;Channing Walton&lt;/h2&gt;
&lt;p&gt;Contrived Java Example:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;/**
 * A source of messages (serializable objects).
 * Implementations may be JMS queues, file systems, etc.
 */
public abstract class Source {
    /**
     * Receive a Message from the Source.
     * @param timeout length of time in ms to wait for a message
     * @return a message or null if the source timed out
     */
    public abstract Serializable receive(long timeout) ;
    }

    public abstract class AbstractSourceTestCase extends TestCase {
        /**
         * Get the Source to test
         */
        public abstract Source getSource() ;

        /**
         * Prepare and get a message expected from the Source.
         * e.g. put a message on to a JMS queue so that 
         * a JMS Source will then produce it.
         */
        public abstract Serializable prepareAndGetExpectedMessage() ;

        public void testMessageReceived() {
            Serializable expected = prepareAndGetExpectedMessage();
            Serializable received = getSource().receive(1000);
            assertEquals(expected, received);
        }

        public void testNoMessageReceived() {
            Serializable received = getSource().receive(1000);
            assertTrue(received == null);
        }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OK, so the above example is a little contrived but is based on something I have written and found very useful. My ‘real’ Abstract Test Case has about 9 test methods which would have been replicated for all the tests for my implementations - lots of effort saved and it has caught a number of subtle bugs.&lt;/p&gt;
&lt;p&gt;Given that an abstract class defines the behaviour of concrete implementations, an Abstract Test Case tests that behaviour and ensures that implementations behave as expected. It also helps developers build new implementations - the new test case implementing the Abstract Test Case helps them to do it much more easily.&lt;/p&gt;
&lt;h2 id=&quot;discussions&quot;&gt;Discussions&lt;/h2&gt;
&lt;p&gt;This technique is not applicable to all Abstract Classes as one expects different behaviour in concrete implementations that might make it impossible to use this technique. —Channing Walton&lt;/p&gt;
&lt;p&gt;If you follow the Liskov Substitution Principle, then this should not be a problem. —Anonymous/uncredited&lt;/p&gt;
&lt;p&gt;Indeed. In fact I am struggling to find a case where Abstract Test Cases wouldn’t work, it would be nice to have a list of exceptions if any. —Channing Walton&lt;/p&gt;
&lt;p&gt;This kind of test case ensures that concrete classes do not violate the contracts of their superclasses. Assuming there is no extra behavior to test, this is sufficient. If there is more to test in the concrete class, then there needs to be an additional test case for that extra behavior. —J. B. Rainsberger&lt;/p&gt;
&lt;p&gt;Exactly so! That’s what I wanted to say and was unable to find the words :-) When I have a class that implements two interfaces, I have had to write two or maybe three Test Cases for it, one for each of the interfaces it implements (a &lt;code&gt;TestFooAsX&lt;/code&gt; and &lt;code&gt;TestFooAsY&lt;/code&gt;), and another test for anything else. —Channing Walton&lt;/p&gt;
&lt;p&gt;Real-life example: I wish IBM/Visual Age for Java had been more careful. I was working with EJBs/Access Beans and wrote a test.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public void testFindOnlyOne() throws Exception {
    MyAccessBean finder = new MyAccessBean();
    Enumeration e = finder.findByUniqueIndex(); // Expect one row
    assertTrue(e.hasMoreElements());
    MyAccessBean first = (MyAccessBean) e.nextElement();
    assertTrue(!e.hasMoreElements());   // Shouldn&amp;#39;t be any more.
    try {
        e.nextElement();
        fail(&amp;quot;There&amp;#39;s more?! You just said there wasn&amp;#39;t!&amp;quot;);
    }
    catch (NoSuchElementException success) {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This test failed. Why? &lt;code&gt;com.ibm.ivj.ejb.runtime.AccessBeanEnumeration&lt;/code&gt; does not respect the contract of &lt;code&gt;java.util.Enumeration&lt;/code&gt;. When &lt;code&gt;hasMoreElements()&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;nextElement()&lt;/code&gt; returns &lt;code&gt;null&lt;/code&gt; instead of throwing &lt;code&gt;NoSuchElementException&lt;/code&gt;. In short, their “enumeration” is not an &lt;code&gt;Enumeration&lt;/code&gt;, even though they implement that interface.&lt;/p&gt;
&lt;p&gt;An abstract test case enforcing the contract of &lt;code&gt;java.util.Enumeration&lt;/code&gt; would have helped here. —J. B. Rainsberger&lt;/p&gt;
&lt;p&gt;Perhaps API designers should include abstract test cases too ;) —Channing Walton&lt;/p&gt;
&lt;p&gt;I completely agree with that last comment. I recently had to implement a JSR and frequently found myself wishing that it was specified in terms of tests rather than a large document that I had to repeatedly reference and make judgement calls about what the authors intended. —James Abley&lt;/p&gt;
&lt;/sectionk&gt;&lt;br /&gt;

&lt;/details&gt;
</description>
        <pubDate>Tue, 23 Feb 2021 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/abstract-test-cases-20-years-later</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/abstract-test-cases-20-years-later</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>11ty By Intention</title>
        <description>&lt;p&gt;Over at &lt;a href=&quot;https://the260bowler.ca&quot;&gt;The 260 Bowler&lt;/a&gt; I’ve added a handful of diary entries (just &lt;em&gt;blog posts&lt;/em&gt;), so now I want a diary page (think &lt;em&gt;recent posts&lt;/em&gt;). I started simply, iterating over all the entries, summarizing them, then starting to add nice styles so that they look vaguely like a diary page. I’ll make it look really nice before I move on.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/11ty-by-intention/diary-page-before.png&quot; title=&quot;fig:&quot; alt=&quot;I’m designing mobile-first. Are you proud of me?&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;I thought, “Hey! I should show these in reverse order, and then limit then to something like 5 or 10 entries.” When I thought about how to do that, I immediately jumped to writing Nunjucks filters, since that’s how I did things with Jekyll and Liquid. I had in mind something like this:&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;{% for entry in collections.diary_entries | reverse | limit(5) %}
[...]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I started trying to build some Nunjucks filters, when I realized that I could simply things considerably by writing the whole thing natively in Javascript. (This is one of the primary advantages of 11ty: the configuration is Javascript, which removes 99% of the resistance to extending the “language” of the site.) This opens up the opportunity to do something that we know and love: &lt;strong&gt;programming by intention&lt;/strong&gt;.&lt;/p&gt;
&lt;details class=&quot;aside&quot;&gt;
&lt;summary&gt;
Don’t remember what &lt;strong&gt;programming by intention&lt;/strong&gt; means? Click here.
&lt;/summary&gt;
We &lt;strong&gt;program by intention&lt;/strong&gt; when we focus on the overall workflow and defer implementing the parts. We simply invoke the functions or methods that we wish existed, then implement them later. I often find it helpful to do this when I worry about becoming bogged down in the implementation details. Programming by intention relates strongly to the &lt;strong&gt;Composed Method&lt;/strong&gt; pattern that Kent Beck wrote about in &lt;a href=&quot;https://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent-ebook-dp-B00BBDLIME/dp/B00BBDLIME?&amp;amp;linkCode=ll1&amp;amp;tag=jbrains.ca-20&amp;amp;linkId=d9d1565c73facc4e15fce19c98ebe6e2&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;&lt;em&gt;Smalltalk Best Practice Patterns&lt;/em&gt;&lt;/a&gt;.
&lt;/details&gt;
&lt;p&gt;Programming by intention generally means &lt;strong&gt;attending to names&lt;/strong&gt;, so I started there:&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;{% for entry in collections.recent_diary_entries %}
[...]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, I felt free to express myself completely in Javascript, rather than feel restricted by the syntax of a template language such as Nunjucks or Liquid.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// Inside a function that uses eleventyConfig as a Collecting Parameter

// shouldPublishDiaryEntry :: Post -&amp;gt; Boolean

const collectRecentDiaryEntries = (collection) =&amp;gt;
  collection.getAllSorted().filter(shouldPublishDiaryEntry).reverse();

eleventyConfig.addCollection(
  &amp;quot;recent_diary_entries&amp;quot;,
  collectRecentDiaryEntries
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, I typed in the Obvious Implementation and &lt;em&gt;it just worked&lt;/em&gt;.&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;https://media.giphy.com/media/o75ajIFH0QnQC3nCeD/giphy.gif&quot; /&gt;
&lt;/figure&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;11ty Documentation, &lt;a href=&quot;https://www.11ty.dev/docs/shortcodes/&quot;&gt;“Shortcodes”&lt;/a&gt;. A reference on adding &lt;em&gt;shortcodes&lt;/em&gt;, which act like library functions.&lt;/p&gt;
&lt;p&gt;Kent Beck, &lt;a href=&quot;https://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent-ebook-dp-B00BBDLIME/dp/B00BBDLIME?&amp;amp;linkCode=ll1&amp;amp;tag=jbrains.ca-20&amp;amp;linkId=d9d1565c73facc4e15fce19c98ebe6e2&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;&lt;em&gt;Smalltalk Best Practice Patterns&lt;/em&gt;&lt;/a&gt;. I recommend this, whether you ever intend to write Smalltalk or don’t.&lt;/p&gt;
&lt;p&gt;Jeff Langr, &lt;a href=&quot;https://www.amazon.com/Essential-Java-Style-Patterns-Implementation/dp/0130850861?&amp;amp;linkCode=ll1&amp;amp;tag=jbrains.ca-20&amp;amp;linkId=8705510187eb5691e7c769a6641494a0&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;&lt;em&gt;Essential Java Style: Patterns for Implementation&lt;/em&gt;&lt;/a&gt;. If you just can’t read a book on Smalltalk, then read this one, which is very much the same book, but in Java. From 1999. It’s fine.&lt;/p&gt;
</description>
        <pubDate>Mon, 15 Feb 2021 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/11ty-by-intention</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/11ty-by-intention</guid>
        
        
        <category>Adventures in 11ty</category>
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Removing Duplication Deftly 1</title>
        <description>&lt;p&gt;In my evolutionary design practice, I consider &lt;em&gt;removing duplication&lt;/em&gt; one of the three fundamental moves.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; Accordingly, I practise this move daily and trust it as a primary tactic for understanding the needs of the design. I would like to share a little example with you.&lt;/p&gt;
&lt;p&gt;We encountered this example during a session of &lt;a href=&quot;https://pubmob.com/offerings/jbrains-evolutionary-design-without-tests/&quot;&gt;Evolutionary Design Without* Tests&lt;/a&gt;. We’re adding a feature to the Point of Sale system: adding &lt;em&gt;provincial sales tax&lt;/em&gt; to each item as the shopper purchases it. The system already supported &lt;em&gt;federal sales tax&lt;/em&gt;, so here we were adding essentially the same behavior with some slightly different parameters.&lt;/p&gt;
&lt;p&gt;We added behavior to the user interface, but we got it wrong. When the cashier scans a product that attracts taxes, the Customer wants to see something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$17.95 GP&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, “G” signifies the federal sales tax, called “GST” in Canada, while “P” signifies the provincial sales tax, called “PST” in (parts of) Canada.&lt;/p&gt;
&lt;p&gt;Although the Customer wants to see this, they see this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$17.95 G P&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We clarified with the Customer that they want to see whitespace between the &lt;em&gt;net price&lt;/em&gt; and the &lt;em&gt;sales tax indicators&lt;/em&gt;, but that when the product attracts multiple sales taxes, to show all the indicators “bunched together” without intervening whitespace. We then set about fixing this UI defect.&lt;/p&gt;
&lt;h2 id=&quot;fixing-the-ui-defect&quot;&gt;Fixing the UI Defect&lt;/h2&gt;
&lt;p&gt;We isolated the defect to &lt;em&gt;formatting the price of a product&lt;/em&gt;, the code for which we find in &lt;code&gt;Product&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public class Product {
    [...]
    private final int netPrice;
    private final boolean gstApplies;
    private final boolean pstApplies;

    [...]
    public String formatPrice() {
        final String gstApplied = gstApplies ? &amp;quot; G&amp;quot; : &amp;quot;&amp;quot;;
        final String pstApplied = pstApplies ? &amp;quot; P&amp;quot; : &amp;quot;&amp;quot;;
        return String.format(&amp;quot;$%.2f%s%s&amp;quot;, netPrice / 100d, gstApplied, pstApplied);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I presume that you see the duplication between &lt;code&gt;gstApplied&lt;/code&gt; and &lt;code&gt;pstApplied&lt;/code&gt;. &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;My intuition tells me&lt;/a&gt; to classify this as &lt;em&gt;essential&lt;/em&gt; duplication&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; and I judge it easy to remove, so I choose to do it now. (In other situations, I might invoke the &lt;em&gt;Rule of Three&lt;/em&gt; and not remove the duplication until I saw a third variation of the code.) I propose the following microsteps.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Isolate the leading space characters in &quot; G&quot; and &quot; P&quot;. &lt;strong&gt;Separate the identical parts from the differences&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Introduce a temporary variable for the leading space. &lt;strong&gt;Collect the identical parts, leaving behind the differences&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The act of introducing a temporary variable forces us to &lt;em&gt;name&lt;/em&gt; the leading space value. When we discussed the options for names, we chose an &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names&quot;&gt;accurate-but-vague&lt;/a&gt; name &lt;code&gt;anyTaxApplied&lt;/code&gt;. &lt;strong&gt;Type what you say&lt;/strong&gt;. This name revealed to us the exact nature of the defect: the code adds the “leading space”, even when there is nothing to “lead”, in spite of the fact that &lt;em&gt;we know&lt;/em&gt; that we want a leading space only if at least one tax has applied to the purchase.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;    public String formatPrice() {
        // DEFECT We include this even when no taxes apply.
        final String anyTaxApplied = &amp;quot; &amp;quot;;
        final String gstApplied = gstApplies ? anyTaxApplied + &amp;quot;G&amp;quot; : &amp;quot;&amp;quot;;
        final String pstApplied = pstApplies ? anyTaxApplied + &amp;quot;P&amp;quot; : &amp;quot;&amp;quot;;
        return String.format(&amp;quot;$%.2f%s%s&amp;quot;, netPrice / 100d, gstApplied, pstApplied);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it seems quite clear how to fix the defect: move formatting the leading space into the &lt;code&gt;format()&lt;/code&gt; line. &lt;strong&gt;This removes damaging duplication&lt;/strong&gt;, namely &lt;em&gt;always&lt;/em&gt; doing something that we ought to do only &lt;em&gt;sometimes&lt;/em&gt;. &lt;strong&gt;Sometimes, trying to remove duplication results in fixing defects as a side-effect&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We chose to fix the behavior as soon as we could safely do that, then &lt;strong&gt;clean up before moving on&lt;/strong&gt;.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Change &lt;code&gt;anyTaxApplied&lt;/code&gt; to “one space if either tax applies, otherwise empty”. &lt;strong&gt;Match the name to the code&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Format &lt;code&gt;anyTaxApplied&lt;/code&gt; directly in the &lt;code&gt;format()&lt;/code&gt; line, rather than as part of &lt;code&gt;gstApplied&lt;/code&gt; and &lt;code&gt;pstApplied&lt;/code&gt;. &lt;strong&gt;Remove duplication&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We end up with here. I feel content with this code.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;    public String formatPrice() {
        final String anyTaxApplied = gstApplies || pstApplies ? &amp;quot; &amp;quot; : &amp;quot;&amp;quot;;
        final String gstApplied = gstApplies ? &amp;quot;G&amp;quot; : &amp;quot;&amp;quot;;
        final String pstApplied = pstApplies ? &amp;quot;P&amp;quot; : &amp;quot;&amp;quot;;
        // REFACTOR Use formatMonetaryAmount() for this
        return String.format(&amp;quot;$%.2f%s%s%s&amp;quot;, netPrice / 100d, anyTaxApplied, gstApplied, pstApplied);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;future-refactorings&quot;&gt;Future Refactorings&lt;/h2&gt;
&lt;p&gt;I can already see a direction this code might go: first to Maybe sales taxes and perhaps eventually to a List of sales taxes. This would help us deal with a more trickier form a duplication in the design. I’ll leave the details of that to a future article.&lt;/p&gt;
&lt;h2 id=&quot;that-felt-slow&quot;&gt;That Felt Slow&lt;/h2&gt;
&lt;p&gt;It always feels slow when we read about it. According to the commit logs, the entire change happened in less than 2 minutes, once we agreed on the presence of the defect, including the 5 commits.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest&quot;&gt;“Putting An Age-Old Battle To Rest”&lt;/a&gt;. Turn the four elements of simple design into a continuous improvement machine.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names&quot;&gt;“A Model for Improving Names”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;“Becoming An Accomplished Software Designer”&lt;/a&gt;. I can make design decisions either intuitively or mechanically. Both work well. When they agree, so much the better.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-two-minute-rule&quot;&gt;“The Two-Minute Rule”&lt;/a&gt;. Not my idea. Part of &lt;em&gt;Getting Things Done&lt;/em&gt;. If you can do it in less than two minutes, then do it now, otherwise put it in the inbox to process later.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I think of these as the three fundamental movies: make a new test pass, remove duplication, improve a name. They form the &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Simple Design Dynamo&lt;/a&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Duplication that appears to come from the problem domain, as opposed to purely from an accident of how we’ve written the code so far.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 08 Feb 2021 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/removing-duplication-deftly-1</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/removing-duplication-deftly-1</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
        <category>Removing Duplication Deftly</category>
        
      </item>
    
      <item>
        <title>Deciphering An 11ty Error Message</title>
        <description>&lt;p&gt;I recently started a &lt;a href=&quot;https://the260bowler.ca/&quot;&gt;new project&lt;/a&gt; and used this as an opportunity to learn and practise a few things, among which we find &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty, a static site generator&lt;/a&gt;. I fancy myself a static site generator hipster—I did it before people called it “JAMstack” and made it cool—first with Octopress, then with &lt;a href=&quot;https://www.jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;. Indeed, I’ve built my other sites with Jekyll and even built the occasional plug-in, taking advantage of my experience working in Ruby.&lt;/p&gt;
&lt;p&gt;In spite of my successes with Jekyll, I became especially enamored with the idea of a configuration system based on a programming language (Javascript in the case of 11ty), rather than a file format (such as &lt;strong&gt;yaml&lt;/strong&gt;), due to the potential for flexible configuration without adding a preprocessing step to building the site. Various people had alerted me to Hugo, Gatsby, and 11ty, and I decided that now felt like a suitable time to experiment. I didn’t want to work in &lt;strong&gt;go&lt;/strong&gt; nor &lt;strong&gt;React&lt;/strong&gt;, so that left 11ty as the candidate.&lt;/p&gt;
&lt;p&gt;After a bumpy start, as seems common when learning a new platform, I began to settle in and gradually noticed myself starting to ship new content with decreasing friction. I had learned the very basics and could at least write posts and link pages to each other. I even made it through a particularly rough episode of forgetting that 11ty was using Liquid to process my Markdown pages, even though those pages were using Nunjucks templates for layouts. I won’t lie: that episode shook my faith in the entire project for a few hours, but after sleeping on it, I felt better.&lt;/p&gt;
&lt;p&gt;So imagine by surprise when, as I was minding my own business, refactoring my 11ty site, this happened.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ DEBUG=Eleventy* npm run build
[... many things ...]
`Template render error` was thrown:
$TIMESTAMP Eleventy:EleventyErrorHandler (error stack): Template render error: (./source/_includes/$LAYOUT_TEMPLATE_NAME.njk)
  TypeError: collection is not iterable
    at Object._prettifyError (/home/jbrains/Workspaces/the260bowler.ca/node_modules/nunjucks/src/lib.js:36:11)
    at /home/jbrains/Workspaces/the260bowler.ca/node_modules/nunjucks/src/environment.js:561:19
    at Template.root [as rootRenderFunc] (eval at _compile (/home/jbrains/Workspaces/the260bowler.ca/node_modules/nunjucks/src/environment.js:631:
18), &amp;lt;anonymous&amp;gt;:59:3)
    at Template.render (/home/jbrains/Workspaces/the260bowler.ca/node_modules/nunjucks/src/environment.js:550:10)
    at /home/jbrains/Workspaces/the260bowler.ca/node_modules/@11ty/eleventy/src/Engines/Nunjucks.js:236:14
    at new Promise (&amp;lt;anonymous&amp;gt;)
    at /home/jbrains/Workspaces/the260bowler.ca/node_modules/@11ty/eleventy/src/Engines/Nunjucks.js:235:14
    at TemplateLayout.render (/home/jbrains/Workspaces/the260bowler.ca/node_modules/@11ty/eleventy/src/TemplateLayout.js:152:31)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)
    at async Template.renderPageEntry (/home/jbrains/Workspaces/the260bowler.ca/node_modules/@11ty/eleventy/src/Template.js:603:17)
[...many more things...]&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;/images/icons/noun_decrypt_2120627.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;This happened when I tried to replace a &lt;a href=&quot;https://11ty.rocks/posts/create-your-first-basic-11ty-website/#create-posts-collection-via-tags&quot;&gt;tag-based collection of posts&lt;/a&gt; with &lt;a href=&quot;https://www.pborenstein.com/posts/collections/&quot;&gt;an explicit collection of posts&lt;/a&gt;, following Philip Borenstein’s the helpful advice. (Thank you!) These kinds of errors create significant resistance for newcomers to a platform. I didn’t know at the moment how to interpret the error message: literally or as a distraction from the real problem? I didn’t (and still don’t) know 11ty well enough to judge.&lt;/p&gt;
&lt;p&gt;After recovering from my mild disappointment and vague frustration, I was able to fall back on the Ratchet Effect of incremental development and microcommitting: I couldn’t have fallen too far, so I must have made the mistake quite recently, which meant that I knew more or less where to look.&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;/images/icons/noun_Story_2658653.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Here is the story of how I arrived at this point. I hope you’re sitting comfortably.&lt;/p&gt;
&lt;p&gt;Once upon a time, I wrote a few sample blog posts, which I think of as “diary entries”, at least for this project. Since I had followed &lt;a href=&quot;https://11ty.rocks/posts/create-your-first-basic-11ty-website/&quot;&gt;Stephanie Eckles’ instructions&lt;/a&gt; when I first created the site, I had tagged every diary entry as “diary entries” by putting a &lt;code&gt;diary.json&lt;/code&gt; file inside my &lt;code&gt;diary&lt;/code&gt; folder. This JSON file contained the entry &lt;code&gt;tags: diary_entries&lt;/code&gt; so that &lt;em&gt;every&lt;/em&gt; document inside that directory would have this tag in its front matter/metadata. Accordingly, 11ty would create a Page Collection called &lt;code&gt;diary_entries&lt;/code&gt; that I could use in my Nunjucks templates as &lt;code&gt;\{\{ collections.diary_entries \}\}&lt;/code&gt;. I understood this, I did it correctly, and all seemed well.&lt;/p&gt;
&lt;p&gt;One day, I decided to refactor my 11ty site, changing how I marked these diary entries as members of the Page Collection &lt;code&gt;diary_entries&lt;/code&gt;. I would write a function in the 11ty configuration file to collect all the pages marked with the metadata attribute &lt;code&gt;diary_entry: true&lt;/code&gt; instead of relying on the convention of using a tag. I wrote a function &lt;code&gt;collectDiaryEntries()&lt;/code&gt; to do exactly that. I understood it and I felt good about it.&lt;/p&gt;
&lt;p&gt;So far, I’d followed the sage advice I’d learned two decades ago from Kent Beck. When changing the implementation details:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Add the new implementation.&lt;/li&gt;
&lt;li&gt;Migrate the clients.&lt;/li&gt;
&lt;li&gt;Remove the old implementation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When we follow these steps, we change behavior safely, as opposed to ripping out the old thing, then jamming in the new thing under pressure and hammering on it until it works. Delightful!&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;/images/icons/noun_Rain_39335.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Just as I tried to remove the &lt;code&gt;tags: diary_entries&lt;/code&gt; metadata from &lt;code&gt;diary.json&lt;/code&gt;, in order to migrate from the implicit, magical tag-based implementation to the explicit, transparent add-a-collection-based implementation, thunder cracked in the distance. Lightning struck a few seconds later only a few metres from where I sat.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;TypeError: collection is not iterable&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fortunately, I had been committing small, independent changes frequently, so once I got past the immediate annoyance over the terse error message, I found the source of the problem.&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;/images/icons/noun_cloudy_2691334.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;I know that if I take a deep breath and just &lt;em&gt;look&lt;/em&gt; at what I’ve done, I often notice the problem quite quickly. I started laughing within seconds. Can you spot the mistake?&lt;/p&gt;
&lt;pre class=&quot;diff&quot;&gt;&lt;code&gt; eleventy-config.js      | 12 ++++++++++++
 source/diary/diary.json |  2 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/eleventy-config.js b/eleventy-config.js
index bfce2fa6d1f05afce9c13416213258c3c2584d83..6348ff9cdef727e9dcb34807ffc55dfafc43d6f2 100644
--- a/eleventy-config.js
+++ b/eleventy-config.js
@@ -72,6 +72,15 @@ const shortcodesForInterstitialVisualElements = function (eleventyConfig) {
   );
 };
 
+const collectDiaryEntries = function (eleventyConfig) {
+  const isDiaryEntry = (item) =&amp;gt;
+    item.data.diary_entry &amp;amp;&amp;amp; item.data.diary_entry === &amp;quot;true&amp;quot;;
+
+  eleventyConfig.addCollection(&amp;quot;diary_entries&amp;quot;, (collection) =&amp;gt; {
+    return collection.getAllSorted().filter(isDiaryEntry);
+  });
+};
+
 const dynamicAssetsSourcePath = &amp;quot;source&amp;quot;;
 module.exports = function (eleventyConfig) {
   enableRss(eleventyConfig);

   filtersForFormattingDates(eleventyConfig);
   shortcodesForInterstitialVisualElements(eleventyConfig);
 
   buildRules(eleventyConfig);
 
   return {
diff --git a/source/diary/diary.json b/source/diary/diary.json
index 480a24c665f7a17211ad286164cf1bf4f567b176..5f00c03a887e79a129bd031d8020146edbd180a0 100644
--- a/source/diary/diary.json
+++ b/source/diary/diary.json
@@ -1 +1 @@
-{ &amp;quot;layout&amp;quot;: &amp;quot;diary-entry.njk&amp;quot;, &amp;quot;tags&amp;quot;: &amp;quot;diary_entries&amp;quot;, &amp;quot;permalink&amp;quot;: &amp;quot;/diary/{{ title | replace(&amp;#39;:&amp;#39;, &amp;#39;&amp;#39;) | slug }}/index.html&amp;quot; }
+{ &amp;quot;layout&amp;quot;: &amp;quot;diary-entry.njk&amp;quot;, &amp;quot;diary_entry&amp;quot;: &amp;quot;true&amp;quot;, &amp;quot;permalink&amp;quot;: &amp;quot;/diary/{{ title | replace(&amp;#39;:&amp;#39;, &amp;#39;&amp;#39;) | slug }}/index.html&amp;quot; }&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;https://media.giphy.com/media/5PkWUpoNuubjSeiyaU/giphy.gif&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;I &lt;em&gt;wrote&lt;/em&gt; the function &lt;code&gt;collectDiaryEntries()&lt;/code&gt; to ask 11ty to add a &lt;code&gt;diary_entries&lt;/code&gt; Page Collection, but I didn’t &lt;em&gt;invoke&lt;/em&gt; the function &lt;code&gt;collectDiaryEntries()&lt;/code&gt; to ask 11ty to add a &lt;code&gt;diary_entries&lt;/code&gt; Page Collection.&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;https://media.giphy.com/media/5t9pOg5hFJ7E8SJ4mi/giphy.gif&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;When I removed the &lt;code&gt;diary_entries&lt;/code&gt; tag from all the pages in the &lt;code&gt;diary&lt;/code&gt; folder, I was left with “previous entry” and “next entry” links trying to refer to a Page Collection that did not exist. Evidently, in this context, the error message means “&lt;code&gt;diary_entries&lt;/code&gt;? Which &lt;code&gt;diary_entries&lt;/code&gt;? Never heard of it.”&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;https://media.giphy.com/media/80mXWlPqTSU1y/giphy.gif&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;OK… now that I know what I’m looking for, I can make sense of this message:&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;TypeError: collection is not iterable&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“OK, this thing I’m calling &lt;code&gt;collection&lt;/code&gt;, I tried doing some iterating on it and that totally didn’t work.”&lt;/p&gt;
&lt;figure class=&quot;interstitial-visual-element&quot;&gt;
&lt;img src=&quot;/images/icons/noun_Repair_3194681.png&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;By now, you know how the story ends.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt; eleventy-config.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/eleventy-config.js b/eleventy-config.js
index 6348ff9cdef727e9dcb34807ffc55dfafc43d6f2..015a33fa15276ce1206e3af6658da90188739133 100644
--- a/eleventy-config.js
+++ b/eleventy-config.js
@@ -89,8 +89,7 @@ module.exports = function (eleventyConfig) {
   filtersForFormattingDates(eleventyConfig);
   shortcodesForInterstitialVisualElements(eleventyConfig);
 
+  collectDiaryEntries(eleventyConfig);
 
   buildRules(eleventyConfig);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great success!&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Stephanie Eckles, &lt;a href=&quot;https://11ty.rocks/posts/create-your-first-basic-11ty-website&quot;&gt;“Create Your First Basic 11ty Website”&lt;/a&gt;. I really enjoyed this tutorial. If you wish to get started with 11ty, then I encourage you to start here.&lt;/p&gt;
&lt;p&gt;Philip Borenstein, &lt;a href=&quot;https://www.pborenstein.com/posts/collections/&quot;&gt;“Working with Collections”&lt;/a&gt;. Clear, simple, concise.&lt;/p&gt;
</description>
        <pubDate>Mon, 01 Feb 2021 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/deciphering-an-11ty-error-message</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/deciphering-an-11ty-error-message</guid>
        
        
        <category>Adventures in 11ty</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>Too Many Ifs? Maybe.</title>
        <description>&lt;p&gt;Complicated code only creates problems when humans try to change it. When we try to change code, we spend energy understanding it, and so we label code “complicated” when it &lt;em&gt;feels&lt;/em&gt; like it requires “too much” energy to understand. That’s why we &lt;em&gt;design&lt;/em&gt; software: we organize code in a way that reduces the cost of understanding it.&lt;/p&gt;
&lt;p&gt;“Too many” &lt;code&gt;if&lt;/code&gt; conditions represents just one way to write complicated code. Most of us don’t immediately grasp long chains or deeply-branching trees of boolean conditions. We sometimes have to draw a truth table in order to trace the various paths. Accordingly, we feel &lt;em&gt;positive pressure&lt;/em&gt; to simplify &lt;code&gt;if&lt;/code&gt; conditions.&lt;/p&gt;
&lt;p&gt;Incidentally, &lt;strong&gt;writing a lot of &lt;code&gt;if&lt;/code&gt; conditions doesn’t automatically become complicated&lt;/strong&gt;. We judge that when we read the code, based on a &lt;em&gt;subconscious judgment about the relative effort to understand it&lt;/em&gt;. We read the code and create an impression of whether it “is too complicated”. On different days, we react differently, sometimes depending on when we last ate food or drank coffee.&lt;/p&gt;
&lt;p&gt;Let’s assume, for the sake of this article, that we on the team who maintain this code generally agree that a given &lt;code&gt;if&lt;/code&gt; block “is too complicated”. How can we simplify the &lt;code&gt;if&lt;/code&gt; conditions? We could try at least these things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name some of the conditions or sub-expressions. &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;Let the names be long, if the extra detail helps the reader understand.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Replace deeply-nested branches with Guard Clauses. Yes, this conflicts with the received wisdom “only allow one exit point per function”. Principles sometimes conflict. As always, use your best judgment.&lt;/li&gt;
&lt;li&gt;Replace deeply-nested branches with a single level of branches, even if that creates duplication among the various conditions. Giving sub-expressions names often helps to reduce the duplication. Often, when I do this, I can spot a higher-level pattern that helps me remove the duplication differently and simplify the entire structure.&lt;/li&gt;
&lt;li&gt;Extract a function/method for the bodies of the first-level branches. This has a similar effect to naming the conditions or sub-expressions, except that we name the &lt;em&gt;actions&lt;/em&gt; instead of the &lt;em&gt;conditions&lt;/em&gt;. Doing this often hides distracting details, making it easier to spot a helpful pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When we name things, we do at least these two helpful things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;We articulate in the code what we understand about the design, so that &lt;strong&gt;future readers don’t need to reverse-engineer that knowledge&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We hide “noise”, leaving behind more “signal”, resulting in a greater “transmission” of information. This &lt;strong&gt;reduces the cost of understanding the code&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’m sure there’s more to say about this topic, but I think the foregoing suffices for now.&lt;/p&gt;
&lt;details class=&quot;highlight&quot;&gt;
&lt;summary&gt;
About Guard Clauses…
&lt;/summary&gt;
&lt;p&gt;When I write a Guard Clause, I get the vague, uneasy feeling that I’ve put the code in “the wrong place”. Typically I see it as an irrelevant detail that I ought to &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;push up the call stack&lt;/a&gt;. You can find an example of this in &lt;a href=&quot;https://wbitdd.jbrains.ca/lectures/136759&quot;&gt;“Sell One Item Part 2”&lt;/a&gt; of &lt;a href=&quot;https://tdd.training&quot;&gt;The World’s Best Intro to TDD: Level 1&lt;/a&gt;, starting around the 2:30 mark of the video.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spoiler Alert&lt;/strong&gt;. If we’ve only created Controller layer so far and we try to write pure user interface behavior there, it feels strange. We don’t resolve that strangeness until we write the text-based user interface, which acts as a client to the Controller layer, and provides a natural place for this UI behavior to “bubble up” to. We finally get there in &lt;a href=&quot;https://wbitdd.jbrains.ca/lectures/203398&quot;&gt;“Tension in Abstraction”&lt;/a&gt; starting around the 11:00 mark of the video. (Please note: this video is &lt;em&gt;not&lt;/em&gt; in the &lt;strong&gt;free preview&lt;/strong&gt; part of the course. Sorry.)&lt;/p&gt;
&lt;/details&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Quora, &lt;a href=&quot;https://www.quora.com/Why-is-using-a-lot-of-if-conditions-not-considered-a-good-computer-programming-practice&quot;&gt;“Why is using a lot of “if” conditions not considered a good computer programming practice?&quot;&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 20 Jan 2021 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/too-many-ifs</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/too-many-ifs</guid>
        
        
        <category>Not Just Coding</category>
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Simulating Failure in Collaboration Tests</title>
        <description>&lt;p&gt;Limiting beliefs and unstated assumptions interfere with our performance. This is not a trifling matter. Here is yet another story of how that happens.&lt;/p&gt;
&lt;details class=&quot;tldr&quot;&gt;
&lt;summary&gt;
TL;DR
&lt;/summary&gt;
&lt;section class=&quot;details&quot;&gt;
&lt;p&gt;We often test a module by connecting it to a &lt;em&gt;lightweight implementation&lt;/em&gt; of one of its collaborators, such as in-memory persistence. This works great for simulating happy paths, but it’s usually impossible to make an in-memory database fail the same ways that an SQL database would fail running on some remote server somewhere. This leads to the question of how do we make the in-memory database simulate the remote database’s failures? We can’t, so I guess we’re out of luck.&lt;/p&gt;
&lt;p&gt;Well, no! Just use different simulators for different tests. Maybe use an in-memory database because it’s convenient for the happy paths, then use a test double library or the Crash Test Dummy pattern to check the failure paths. Why not? Unstated assumptions and limiting beliefs are why not.&lt;/p&gt;
&lt;p&gt;Programmers struggling to learn how to avoid the &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests scam&lt;/a&gt; often assume that they “should” (or worse &lt;em&gt;have to&lt;/em&gt;) use only one kind of test double for all their tests. &lt;strong&gt;They’re so worried about “doing it right” that they don’t have energy left over&lt;/strong&gt; to think about the big picture. Or maybe they’re &lt;strong&gt;so focused on the details that they can’t see the forest for the trees&lt;/strong&gt;. This is normal. That’s why I don’t try to learn something until I know where to find support.&lt;/p&gt;
&lt;p&gt;Knowing where to find experienced people who can answer your questions doesn’t only help you get answers to your questions, but more importantly, &lt;strong&gt;it frees you to focus on the details and allow yourself to struggle&lt;/strong&gt;, but of which are essential for effective learning. You don’t have to worry both about how to do the thing and whether you’re doing “the right” thing. You can get something working, then take a breath, then ask for advice. We all need help like this from time to time, so it helps to have a safe place to ask these kinds of questions where someone with experience can answer them.&lt;/p&gt;
&lt;/section&gt;
&lt;/details&gt;
&lt;h2 id=&quot;the-story&quot;&gt;The Story&lt;/h2&gt;
&lt;p&gt;Consider this common situation: a Controller uses a Repository to store data in a database—a good, old-fashioned relational database management system, such as MySQL. The &lt;em&gt;production implementation&lt;/em&gt; of the Repository will use some MySQL client library to store data in the database. Since &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests are a scam&lt;/a&gt;, you want to check the Controller without integrating it directly to the production Repository, so you connect it to a &lt;em&gt;lightweight implementation&lt;/em&gt; of the Repository, such as a in-memory lookup table of records. This in-memory Repository stores the records in a list or dictionary, making it easy to write Collaboration Tests for the Controller, such as this one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe &amp;quot;&amp;#39;All Users&amp;#39; report&amp;quot; do
  example &amp;quot;happy path&amp;quot; do
    let anyNonEmptyCollectionOfValidUsers = repeat(3, anyUniqueValidUser())
    let repository = InMemoryUserRepository(users: anyNonEmptyCollectionOfValidUsers)
    let controller = AllUsersReportController(repository: repository)

    let response = controller.handleRequest(anyValidRequest())

    response.users shouldEqual anyNonEmptyCollectionOfValidUsers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In words, this test says&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Assuming that the user repository has these 3 users, when the “all users report” controller executes successfully, its response should contain those 3 users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can imagine that some application framework will render the response and show those users in a list on a summary page. That behavior doesn’t affect this test.&lt;/p&gt;
&lt;p&gt;I’d write more tests for the Controller than this, but that’s not what this article is about.&lt;/p&gt;
&lt;h2 id=&quot;a-contract-test-for-user-repositories&quot;&gt;A Contract Test For User Repositories&lt;/h2&gt;
&lt;p&gt;You can also imagine an interface &lt;code&gt;UserRepository&lt;/code&gt; with a method like &lt;code&gt;findAllUsers()&lt;/code&gt;, which the lightweight implementation (in-memory) and the production implementation (MySQL client) both implement. When everything behaves as expected, this Controller happily works with either implementation of &lt;code&gt;UserRepository&lt;/code&gt;. The Controller doesn’t care whether the &lt;code&gt;User&lt;/code&gt; values came from the in-memory repository or a MySQL database. If you wanted, you could write a Contract Test to document that any User Repository returns all its users when a client asks it for all its users.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe &amp;quot;User Repository contracts&amp;quot; do
  describe &amp;quot;findAllUsers()&amp;quot; do
    example &amp;quot;happy path&amp;quot; do
      let anyNonEmptyCollectionOfValidUsers = repeat(3, anyUniqueValidUser())
      let repository = repositoryFactory.seedUserRepository(users: anyNonEmptyCollectionOfValidUsers)
      
      repository.findAllUsers() shouldEqual anyNonEmptyCollectionOfValidUsers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In words, this test says&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Any User Repository’s “find all users” query should return all the users it currently has.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some of you might consider this test too simple to bother writing. In many situations, I’d agree. We might consider some aspects of an interface’s contract so obvious and so simple to respect that we instead spend our precious energy checking other, more complicated parts of the contract.&lt;/p&gt;
&lt;h2 id=&quot;the-database-might-fail-you-know&quot;&gt;The Database Might Fail, You Know&lt;/h2&gt;
&lt;p&gt;Indeed, the database might fail. This sets up the quandary that I wanted to address in this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The production implementation of &lt;code&gt;UserRepository&lt;/code&gt; might raise an error when the underlying database client library detects a failure in trying to communicate with the underlying database. Maybe the database service isn’t running or the network has failed.&lt;/li&gt;
&lt;li&gt;Since &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests are still a scam&lt;/a&gt;, you might prefer to use Collaboration and Contract Tests to check the integration between the Controller and the Repository. You might prefer to use the in-memory lightweight implementation of the Repository, because you find it so simple and easy to use.&lt;/li&gt;
&lt;li&gt;Unfortunately, &lt;strong&gt;an in-memory Repository can’t fail in the ways that a database can&lt;/strong&gt;, which means that you can’t see how to use it to check that the Controller gracefully handles the various failures that can occur in production.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now what? Eleven years after I first answered a certain Stack Overflow question, I received notification of a comment in which someone asked this very question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What would one of the tests in your example look like for testing the behaviour when the backend server is down, and how would you set that condition up in tests? — &lt;a href=&quot;https://stackoverflow.com/questions/2096622/testing-a-interface-repository/2099727?noredirect=1#comment115400110_2099727&quot;&gt;@jrahhali&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;uncovering-an-unstated-assumption&quot;&gt;Uncovering An Unstated Assumption&lt;/h2&gt;
&lt;p&gt;Have you ever had the experience of feeling utterly surprised by a question? I mean that someone asks you a question that causes you to scream an “obvious” answer inside your head. The answer seems so obvious in fact that you wonder why someone would ever ask the question in the first place. Whenever I feel this way, I try to remember to look for an &lt;em&gt;unstated assumption&lt;/em&gt; in the question. The answer seems obvious &lt;em&gt;to me right now&lt;/em&gt; because I haven’t assumed something that the questioner has assumed. If I find that unstated assumption, then all becomes clear.&lt;/p&gt;
&lt;p&gt;Sometimes I can guess the assumption hiding inside the question; sometimes I can’t. I could guess and try to answer &lt;em&gt;that&lt;/em&gt; question, but often that merely annoys the questioner. I try to remember instead merely to ask. &lt;strong&gt;The questioner’s actual assumption matters more to them than the twelve assumptions I can invent in my own mind&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I asked. I got this response:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Say &lt;code&gt;AdoBasedRepositoryUser.GetById()&lt;/code&gt; throws a &lt;code&gt;FooException&lt;/code&gt; when the “backend server is down”. Even though “the backend server is down” behaviour cannot happen in the in-memory version, isn’t this throwing of &lt;code&gt;FooException&lt;/code&gt; part of the behaviour you would want to mimic for &lt;code&gt;MemoryRepositoryUser.GetById()&lt;/code&gt;? — &lt;a href=&quot;https://stackoverflow.com/users/2668666/jrahhali&quot;&gt;@jrahhali&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aha! I’ve seen programmers make this assumption before. It seems like a natural part of the learning process when trying to use Collaboration and Contract Tests to avoid the &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests scam&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Indeed, no, &lt;strong&gt;there is no need to use only one kind of test double to check the entire contract of that interface&lt;/strong&gt;. Since the in-memory User Repository can’t fail because it has no “back end”, we need a different way to simulate “back end failure”. I affectionately refer to the Crash Test Dummy pattern: implementing the interface with methods that intentionally raise errors. For some tests, we use Crash Test Dummies to check how the client reacts to failure.&lt;/p&gt;
&lt;p&gt;Although this solution seems fairly obvious, I can understand how programmers might not easily reach this conclusion, especially when they don’t yet feel confident in their understanding of how to use test doubles (“mock objects”) to write Collaboration Tests. Many of them find themselves distracted by the details of trying to write Collaboration and Contract Tests “correctly”. In such a distracted state, people routinely make all manner of unjustified assumptions.&lt;/p&gt;
&lt;h2 id=&quot;to-the-uncertain-free-choices-can-look-like-rules&quot;&gt;To the Uncertain, Free Choices Can Look Like Rules&lt;/h2&gt;
&lt;p&gt;I’ve written extensively about Collaboration and Contract Testing since the early 2000s. For better or worse, some programmers follow my advice about how to write programmer tests. I’m certainly not the only such adviser. &lt;strong&gt;What we advisers do, programmers try to copy in order to learn&lt;/strong&gt;. Many programmers adopt a Shu-Ha-Ri approach to learning, in which they start by following the recipe closely. Shu-Ha-Ri works best when the student and teacher can communicate directly: the teacher can attend to which details matter and which don’t, while the student focuses on performing the steps correctly. &lt;strong&gt;This works less well when the student can’t ask the teacher a question&lt;/strong&gt;. When the student tries to follow the teacher, they often don’t know which details matter and which don’t. Unable to clarify, they err on the side of following more closely. This can lead the student to make unexpected assumptions about what they need to do.&lt;/p&gt;
&lt;p&gt;I like test double libraries. (Some call them “mock object frameworks”, but I prefer to say “test doubles” and they are mostly not frameworks.) I also prefer consistency. As a result, when I write tests and need test doubles, I tend to write them using a test double library (JMock, NSubstitute, rspec-mock…), even when writing them “by hand” is objectively easier. I tend to value the overall consistency of syntax over optimizing the syntax of any one test. I think of this as applying the Principle of Least Surprise. I freely admit this as a &lt;strong&gt;personal preference&lt;/strong&gt;, rather than promote it as a context-free “best practice”. (On the contrary, I’ve experimented in the last few years with using simple lambda expressions over writing stubs with the test double library. I like the results.) Anyone watching my videos, taking my training courses, or reading my articles could be forgiven for concluding that this consistency &lt;em&gt;matters&lt;/em&gt; in some greater sense—that they &lt;em&gt;should&lt;/em&gt; write their test doubles the same way all the time. If they use a lightweight implementation (like an in-memory database) in one test for one Repository, then they need to use lightweight implementations in all tests for all Repositories for all times.&lt;/p&gt;
&lt;p&gt;And they’d have it wrong.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A free choice, if made often enough and without explanation, can look like a rule&lt;/strong&gt;. You might recognize this as the Cargo Cult effect: observers who don’t understand how causes link to effects invent causal relationships where none exist. In this case, the observer thinks, “since experienced person X always does Y, I should also always do Y”. I see two problems here: the entire statement is wrong on its face &lt;em&gt;and&lt;/em&gt; X doesn’t always do Y, but rather you’ve so far only seen X do Y, perhaps only because X feels comfortable doing Y and so does it most of the time. The observer has &lt;em&gt;assumed&lt;/em&gt; that X doing Y &lt;em&gt;matters&lt;/em&gt; right now, when instead X might merely have a free choice and has arbitrarily chosen do to Y. So it goes with me and test doubles in Collaboration Tests. I like consistency and I feel comfortable with dynamic test doubles, so I use them even in situations in which a simpler alternative would work equally well. And &lt;strong&gt;this amounts entirely to arbitrary personal preference&lt;/strong&gt;. If you prefer to use lightweight implementations—we can argue the merits over coffee some time—then I want you to feel free to use them, but when you need the power of a test double library or a hand-written test double, then I want you to feel free to reach for them.&lt;/p&gt;
&lt;h2 id=&quot;back-to-the-question&quot;&gt;Back To the Question&lt;/h2&gt;
&lt;p&gt;Do we need to mimic the “back end failure” behavior in the lightweight implementation of the User Repository? No. If its &lt;code&gt;findAllUsers()&lt;/code&gt; method never raises an error to signal an underlying failure, then it trivially respects the part of the contract of &lt;code&gt;findAllUsers()&lt;/code&gt; that says “I might raise an error of type X to signal that a failure happened in the course of doing my job”. This design conforms with the LSP. No problems.&lt;/p&gt;
&lt;p&gt;If you want to use an in-memory User Repository for the happy paths, then a Crash Test Dummy for the error paths, then do it. Of course, if these two test double implementations overlap in their behavior, then they have to do so consistently! Fortunately, the happy paths and the error paths seem disjoint to me, so I see no risk here of inconsistent behavior. The test double implementations of User Repository should &lt;em&gt;collectively&lt;/em&gt; cover every aspect of the contract of User Repository—at least up to the limits of your precious time, energy, and money. No single implementation, whether dynamic test double, hand-written spy, or lightweight implementation, must bear that responsibility alone.&lt;/p&gt;
&lt;p&gt;I’ve seen some programmers use the in-memory User Repository as a starting point and then subclass and override &lt;code&gt;findAllUsers()&lt;/code&gt; to intentionally raise an error for the one test that needs this. Doing this carries some risks, but it does the job. In general, this makes the test easier to write (by a tiny bit) in the moment, but creates confusion later to those reading the test. &lt;strong&gt;I prefer to avoid irrelevant details in my tests as a design tool&lt;/strong&gt;, and the in-memory implementations of all the other User Repository methods are irrelevant details in the Collaboration Tests that want to stub &lt;code&gt;findAllUsers()&lt;/code&gt;. In the bad old Java days before dynamic method invocation handlers (introduced in May 2000!), we needed such shortcuts, but not any more. I would rather just implement the User Repository interface directly (such as with a dynamic test double), since it communicates the intent of the test directly, both now and into the future.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Stack Overflow, &lt;a href=&quot;https://stackoverflow.com/questions/2096622/testing-a-interface-repository/2099727?noredirect=1#comment115471164_2099727&quot;&gt;“Testing a [sic] interface repository”&lt;/a&gt;. A question from Stack Overflow, which I answered, and which became the inspiration for this&lt;/p&gt;
</description>
        <pubDate>Thu, 17 Dec 2020 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/limiting-beliefs-and-unstated-assumptions</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/limiting-beliefs-and-unstated-assumptions</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
        <category>Test Doubles</category>
        
        <category>Not Just Coding</category>
        
      </item>
    
      <item>
        <title>A Natural Microflow in TDD</title>
        <description>&lt;p&gt;A reader asked me this question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ve always wondered how does the basic flow of red, green, refactor reconcile with the concept of “make the change easy, then make the easy change”? Does that imply sometimes doing an extra refactoring before the next red [failing test] after deciding what the next change should be or is “make the change easy” referring to non-TDD things like an occasional larger-scale refactoring task?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short: yes to the first option. I often find myself doing this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Write a new failing test.&lt;/li&gt;
&lt;li&gt;Notice a refactoring that would make the next step easier.&lt;/li&gt;
&lt;li&gt;Ignore/delete the new failing test.&lt;/li&gt;
&lt;li&gt;Refactor.&lt;/li&gt;
&lt;li&gt;Rewrite the intended failing test—or occasionally a different one!&lt;/li&gt;
&lt;li&gt;Continue.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If I understand the problem really well, I can often do 1-3 in my head and jump directly to 4. &lt;a href=&quot;/permalink/breaking-through-your-refactoring-rut&quot;&gt;With enough practice&lt;/a&gt; I don’t have to take “the long route” every time and even when I take the long route, I’ve mastered the microsteps, so it takes only a few tens of seconds. The size of the refactoring that I perform in step 4 varies. I find myself needing large-scale refactoring tasks less often in this situation (and indeed in general), as long as I have been guiding the design to evolve over time in smaller steps (my usual way of working). Instead of a needing clean up a big mess, I often clean up a handful of little messes more often. That leads to dancing this little forward-and-back dance more often while mostly avoiding the pain and suffering of a large-scale refactoring task.&lt;/p&gt;
&lt;p&gt;I demonstrate this in &lt;a href=&quot;https://tdd.training/lectures/133270&quot;&gt;The World’s Best Introduction to TDD&lt;/a&gt; with my “Add Fractions” example, which you can watch without purchasing the course.&lt;/p&gt;
&lt;p&gt;Moreover, I can see this forward-and-back dance as a good sign: I’m refactoring when I have evidence that I need it, rather than doing it before I need it. Of course, that doesn’t make speculative refactoring uniformly bad, as long as it doesn’t delay releasing features to waiting customers.&lt;/p&gt;
</description>
        <pubDate>Mon, 03 Aug 2020 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-natural-microflow-in-tdd</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-natural-microflow-in-tdd</guid>
        
        
      </item>
    
      <item>
        <title>Breaking Through Your Refactoring Rut</title>
        <description>&lt;p&gt;Refactoring, the activity, involves the following things.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;improving the design of existing code&lt;/li&gt;
&lt;li&gt;… in a sequence of small transformations&lt;/li&gt;
&lt;li&gt;… that preserve the important behavior of the system&lt;/li&gt;
&lt;li&gt;… which you can complete relatively quickly&lt;/li&gt;
&lt;li&gt;… and which gives you inexpensive options to change direction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Effective refactoring combines the value of Real Options thinking with the care and attention of engineering. It reduces volatility in the marginal cost of adding features. It reduces the overall risk of changing code. As I become more comfortable refactoring, I felt freer from the restrictions of &lt;em&gt;if it ain’t broke, don’t fix it&lt;/em&gt;. So why doesn’t everyone do it all the time?&lt;/p&gt;
&lt;p&gt;In short, many of them don’t make it past the scary part of the learning curve. More to the point, &lt;strong&gt;many of them don’t reach the point where they can think effortlessly about rewriting code as a sequence of high-level refactorings&lt;/strong&gt;. They remain stuck in a rut: a positive feedback loop that trains them to believe that they’ll never refactor effectively enough to make it worth their investment. I think I know at least one reason to become stuck in the this rut and a way to break through it.&lt;/p&gt;
&lt;p&gt;Not enough programmers let the fundamentals of refactoring become effortless. They need to practise or risk forever feeling like “it’s too hard” or “it’s too slow”. Accordingly, they never feel the power of being able to think about big design changes as a sequence of tiny, safe changes. This results in legacy code sooner than it needs to happen. &lt;strong&gt;The programmers who break through this rut give themselves a big advantage in their work&lt;/strong&gt;. Let me tell you more about how I believe this happens.&lt;/p&gt;
&lt;h2 id=&quot;chunking&quot;&gt;Chunking&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;https://images.jbrains.ca/icons/noun_head with a target_2011503.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;Cognitive psychologists talk about &lt;a href=&quot;https://en.wikipedia.org/wiki/Chunking_(psychology)&quot;&gt;&lt;em&gt;chunking&lt;/em&gt;&lt;/a&gt;, a phenomenon in which people can remember things more easily by grouping them in a way that allows them to extract meaning. Chunking uses highly-constrained working memory more efficiently, both making certain tasks less difficult and freeing the person to have more complicated and sophisticated ideas. Not chunking causes the person to remain stuck giving their attention to smaller details, which interferes with the person’s ability to remember the bigger picture and causes them to “solve” the same simpler problems over and over. I hope it seems intuitively reasonable that intentional chunking becomes a useful strategy for developing cognitive skills. Not sure? Think about one of the most elementary and critical skills you ever developed: understanding written language.&lt;/p&gt;
&lt;h3 id=&quot;learning-to-read-involved-a-lot-of-chunking&quot;&gt;Learning to Read Involved a Lot of Chunking&lt;/h3&gt;
&lt;p&gt;Look at the glyphs on this screen that represent the letters in these words. Do you even remember the days when you didn’t immediately recognize them? Do you even remember the days when you weren’t sure that this glyph “a” and this glyph “A” represented the same letter? If you don’t, then I encourage you to try to read words in an alphabet/abugida/adjad you don’t already know, such as &lt;a href=&quot;https://en.wikipedia.org/wiki/Armenian_alphabet&quot;&gt;Armenian&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Ge%CA%BDez_script&quot;&gt;Ge`ez&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Hebrew_alphabet&quot;&gt;Hebrew&lt;/a&gt;. Even before you understand the meaning of the words, you likely have to spend a lot of effort just to decipher the symbols glyphs and map them to their basic sounds. You have to pay attention to every detail. You might not recognize that two glyphs represent the same letter, where we only ever use one of those glyphs when the letter comes at the end of the word. When I try to read Hebrew words, it takes all my effort and I mostly don’t know how to even recognize the letters. And yet some people read Hebrew effortlessly.&lt;/p&gt;
&lt;p&gt;Now become aware of not only how easily you recognize these glyphs in the Latin alphabet, but the sounds typically associated with them in English, then the sounds typically associated with various common combinations of them (like -tion). Become aware of how little effort you put into decoding the glyphs into letters, then into words, then into phrases, then into sentences, then even into overall themes and concepts! &lt;strong&gt;If you can skim this article and get the general idea, then you should thank chunking!&lt;/strong&gt; I can’t skim a text in French very well and I mostly can’t skim a text in Swedish at all, but in English I do it quite effortlessly. All this depends on chunking at various levels: glyphs into letters, letters into sounds, letters and sounds into words, words into phrases… and I built all that up over time with practice. So did you!&lt;/p&gt;
&lt;p&gt;Some people believe that children have a knack for chunking as it relates to language. I don’t know enough to judge, but I see two reasons that children would experience a lot of chunking related to language: they have a very strong motivation to learn language and they really have nothing else to do. The two of these together make it natural for them to &lt;strong&gt;practise recognizing and producing language most of their waking time&lt;/strong&gt; and maybe even in their sleep! Adults could probably achieve the same results if they could approach learning a new language with the single-minded focus of a very young child. (Yes—it’s probably much more complicated than that. The mind is a strange place.)&lt;/p&gt;
&lt;p&gt;I digress. Please permit this generalization: you (neurotypicals) learned how to read your native language well to (mostly) effortlessly skim the average text written in that language. Chunking almost certainly played a central role in this achievement. I propose that we use this idea in how we approach refactoring in particular and evolutionary design in general. First, let’s see developing refactoring skill in terms of chunking.&lt;/p&gt;
&lt;h2 id=&quot;learning-to-refactor-involves-a-lot-of-chunking&quot;&gt;Learning to Refactor Involves a Lot of Chunking&lt;/h2&gt;
&lt;p&gt;I’ve watched hundreds of programmers try to improve at refactoring. Many of them continue to stumble when they try to refactor code. They remain stuck in performing the elementary refactorings safely; they have to pay close attention to almost every step as they go. &lt;strong&gt;Even if they know the general direction in which to nudge the design, they feel awkward or unsteady trying to arrive there through a sequence of safe, reversible, behavior-preserving transformations&lt;/strong&gt;. Their experience doesn’t seem much better even when they have automated refactoring tools to help them. They find it difficult to keep track of the intermediate steps while they perform the smaller ones. They’re not chunking.&lt;/p&gt;
&lt;p&gt;When I pair with such a programmer, I end up keeping track of the intermediate steps for them. It doesn’t seem harder to me when I type compared to when I don’t. I often have the experience of seeing 3-5 intermediate steps ahead while I’m completing the current elementary refactoring (like moving a function from one module to another, leaving a delegating function behind for safety). If the other programmer becomes lost, they finish a step, take a deep breath to recover some energy, then look at me to remind them which small refactoring step to take next. I don’t have to work hard to do that. This is the result of all the chunking I’ve done over the years.&lt;/p&gt;
&lt;p&gt;And therein lies the difference. &lt;strong&gt;The programmers who haven’t chunked get lost easily, grow tired sooner, and either need me to help them push on or give up entirely&lt;/strong&gt;. In the best case, they can’t do it without me and in the worst case, they just give up, rip out the old code and rewrite it. That last strategy fails much more often or at least costs much more than they believe it will. All this because they haven’t chunked enough. Specifically, they haven’t chunked the &lt;em&gt;nanosteps&lt;/em&gt; into &lt;em&gt;microsteps&lt;/em&gt; or the &lt;em&gt;microsteps&lt;/em&gt; into &lt;em&gt;moves&lt;/em&gt;. This doesn’t just slow them down, but it holds them back.&lt;/p&gt;
&lt;h3 id=&quot;some-helpful-terms&quot;&gt;Some Helpful Terms&lt;/h3&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;https://images.jbrains.ca/icons/noun_paraphrase translate_3159905.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;In my lexicon, a &lt;em&gt;nanostep&lt;/em&gt; is something like adding a new field to a class. Another nanostep is finding code that wrote to an existing field and adding code that writes the corresponding value to the new field, keeping their values synchronized with each other. Yet another is remembering the keystroke for “extract variable” so that you can simply type the expression (right-hand value) that you have in mind first, then assign it to a new variable (and let the computer compute the type of the variable for you).&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;microstep&lt;/em&gt; is a collection of related nanosteps, like introducing an interface &lt;em&gt;and&lt;/em&gt; changing a few classes to implement that interface, adding empty/default method implementations to the classes that now need it. Another is pushing a value up out of the constructor into its parameter list. Yet another is remembering that you can either extract a value to a variable before extracting code into a method or you can extract the method first, then introduce the value as a parameter, and which keystrokes in NetBeans make that happen.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;move&lt;/em&gt; is a collection of related microsteps, like inverting the dependency between A and B, where A used to invoke B, but now A fires an event which B subscribes to and handles.&lt;/p&gt;
&lt;h3 id=&quot;why-programmers-need-to-chunk&quot;&gt;Why Programmers Need To Chunk&lt;/h3&gt;
&lt;p&gt;The programmer who doesn’t chunk nanosteps into microsteps and microsteps into moves needs to focus their energy on executing the nanosteps safely. They don’t have enough working memory to remember the sequence of moves that leads to improving the design. They might not have enough working memory even to remember any sequence of microsteps that achieves one of those moves safely and effectively. They burn their energy more quickly, make more mistakes, and give up sooner. Moreover, they don’t train themselves to think of changing big portions of the design as a sequence of safe moves that progress steadily.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The programmer who chunks in this way feels little resistance to making a useful improvement in the design, because they see a sequence of moves that will work&lt;/strong&gt;. They feel little resistance to performing the moves because they see sequences of microsteps that will get there. They feel little resistance to performing the microsteps because they perform the nanosteps unconsciously. Piano players call this “having the notes under one’s fingers”. I can change a method signature in Java using IntelliJ IDEA while looking away and talking to someone, because I have chunked!&lt;/p&gt;
&lt;p&gt;I can think of even intricate moves a single thing, because I’ve chunked enough at the level of nanosteps, microsteps, and even moves. Many of the programmers who practise with me struggle to think of Replace Inheritance with Delegation as a single thing, so it happens quite often that they fight to get through a few steps, make a mistake or two, and then ask me, “Where were we? What’s the next step?” They simply can’t remember what to do next. They haven’t chunked enough at the level of nanosteps and microsteps and so they’ve exhausted their working memory. &lt;strong&gt;This lack of chunking causes them to remain stuck at the level of nanosteps and microsteps indefinitely&lt;/strong&gt;. They don’t progress. And they certainly don’t grow comfortable seeing large-scale changes as a sequence of moves that they can perform confidently, safely, and quickly.&lt;/p&gt;
&lt;div class=&quot;aside&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;The classic book &lt;a href=&quot;#references&quot;&gt;&lt;em&gt;The Pragmatic Programmer&lt;/em&gt;&lt;/a&gt; includes advice on learning one editor really well. This leads to chunking. Some people think of it as “muscle memory”, but it’s more than remembering how to perform the steps of moving text around, but also the act of performing the nanosteps without effort so that you can think about the microsteps and moves instead.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;let-yourself-design-by-shaping-clay&quot;&gt;Let Yourself Design By Shaping Clay&lt;/h2&gt;
&lt;p&gt;I remember learning from Ward Cunningham the metaphor of changing designs like shaping clay. Software “is soft”, he would say, precisely in the way that we can shape it as we need to when we need to. If it costs “too much” to change the design of the software, then often the limit lies in our ability to work the clay. The software has hardened; we might as well be printing circuit boards. I believe that as we chunk at the levels of nanosteps, then microsteps, then moves, we achieve quantum leaps in our ability to work the clay. More to the point, I feel quite confident that those who don’t chunk at those levels will find that software remains forever “hard” to them. We can do better!&lt;/p&gt;
&lt;h2 id=&quot;practise-the-microsteps&quot;&gt;Practise the Microsteps&lt;/h2&gt;
&lt;p&gt;By now you have either stopped reading or you urgently want to know how to chunk these nanosteps and microsteps. I did it by practising, reflecting, and writing. Don’t worry: it sounds worse than it is.&lt;/p&gt;
&lt;p&gt;Most programmers remain stuck in a feedback loop that starts with “I should refactor here” and goes through “I think I need this move”, then “I think I need those microsteps”, then “How do I do step 4 again?!”, followed by “This feels too slow”, and finally giving up. &lt;strong&gt;They never chunk because it feels too slow and it feels too slow because they never chunk&lt;/strong&gt;. Therefore, they need to practise so that they can execute the nanosteps with little conscious effort, making the microsteps easier to repeat. They need to practise so that they can execute the microsteps with little conscious effort, making the moves easier to repeat. And so on. You can do this.&lt;/p&gt;
&lt;p&gt;It also helps to write about what you’re doing. You can do this by answering elementary questions about refactoring on web sites like Stack Overflow, Quora, in Slack channels, and various other bulletin boards, message groups, or forums. You can also do this by asking questions in those places, describing what you’ve tried, so that others can judge where you’ve gone wrong or got stuck. It doesn’t matter whether anyone’s reading, so long as you’re writing! When you write about your practice, you reflect on it. As you do this, chunking happens. You couldn’t even stop it if you tried!&lt;/p&gt;
&lt;p&gt;If you don’t feel comfortable practising “for real”, because you don’t want to mess up code from your day job, then you can try practice drills like this one. (And yes, I’ve done this with real clients who paid me real money and it helped them!)&lt;/p&gt;
&lt;h3 id=&quot;practice-drill-replace-one-with-many&quot;&gt;Practice Drill: Replace One With Many&lt;/h3&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;https://images.jbrains.ca/icons/noun_computing_1876210.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;We often need to replace one implementation of a thing with another one. We follow the safe approach of adding the new thing, migrating the clients, then removing the old thing. We can practise this by generalizing a single thing to a collection of things. We can start small by changing a function parameter, but later we could try the same thing with a field (member variable). First, let me describe the nanosteps and microsteps, then I’ll describe a way to practise them.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Identify a function parameter &lt;code&gt;x&lt;/code&gt; which is a single thing. You’ll replace this with &lt;code&gt;xs&lt;/code&gt;, a collection of the same kind of things. I’ll call the function &lt;code&gt;f()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add parameter &lt;code&gt;xs&lt;/code&gt; to function &lt;code&gt;f()&lt;/code&gt; safely, so that all the code that invokes &lt;code&gt;f()&lt;/code&gt; passes in the equivalent parameter to the one it passes now. For example, if it passes &lt;code&gt;12&lt;/code&gt; for &lt;code&gt;x&lt;/code&gt;, then add another argument &lt;code&gt;[12]&lt;/code&gt; for &lt;code&gt;xs&lt;/code&gt;. (Here, &lt;code&gt;[12]&lt;/code&gt; is a collection of one item, &lt;code&gt;12&lt;/code&gt;. In Java, this might be &lt;code&gt;Arrays.asList(12)&lt;/code&gt;). &lt;strong&gt;Change all the code that invokes &lt;code&gt;f()&lt;/code&gt; before moving to the next step.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Focus on the body of &lt;code&gt;f()&lt;/code&gt;. Find the first place that reads &lt;code&gt;x&lt;/code&gt;. Replace that with code that reads from the only element of &lt;code&gt;xs&lt;/code&gt;. In Java, this might be &lt;code&gt;xs.iterator().next()&lt;/code&gt;, whereas in Ruby this might be &lt;code&gt;xs.first&lt;/code&gt; or &lt;code&gt;xs[0]&lt;/code&gt;. Repeat this step for every place inside &lt;code&gt;f()&lt;/code&gt; that reads &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Find the first place that writes to &lt;code&gt;x&lt;/code&gt;. Add code that also writes the same value to &lt;code&gt;xs&lt;/code&gt;. Be careful! You will find it safer to reassign a new value to &lt;code&gt;xs&lt;/code&gt;, rather than changing the value of its only element, if you work in a language that passes collections by reference! Repeat this step for every place inside &lt;code&gt;f()&lt;/code&gt; that writes to &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It should now be true that &lt;code&gt;f()&lt;/code&gt; does not touch &lt;code&gt;x&lt;/code&gt;, but rather only &lt;code&gt;xs&lt;/code&gt;. Verify this. Once you do that, delete all the code that touches &lt;code&gt;x&lt;/code&gt;, but do not delete the parameter yet.&lt;/li&gt;
&lt;li&gt;Go to all the code that invokes &lt;code&gt;f()&lt;/code&gt; and stop passing a value for &lt;code&gt;x&lt;/code&gt;. If your language lets you pass &lt;code&gt;null&lt;/code&gt;, do so. If not, then pass any kind of nonsense value. &lt;strong&gt;Change all the code that invokes &lt;code&gt;f()&lt;/code&gt; before moving to the next step&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Remove &lt;code&gt;x&lt;/code&gt; as a parameter from &lt;code&gt;f()&lt;/code&gt; and remove the corresponding argument from all the code that invokes &lt;code&gt;f()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Focus on the body of &lt;code&gt;f()&lt;/code&gt;. Find the first place that explicitly assumes that &lt;code&gt;xs&lt;/code&gt; has only one element and replace it with iteration (a loop, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;… whatever you need). Repeat this step for every place inside &lt;code&gt;f()&lt;/code&gt; that explicitly talks to the only element of &lt;code&gt;xs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It should now be true that &lt;code&gt;f()&lt;/code&gt; only uses &lt;code&gt;xs&lt;/code&gt; by iterating over the collection somehow. The generalization should be complete. Verify this. Once you verify this, you have finished the refactoring.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now try to follow these steps in some code. Any code. It doesn’t matter which code you choose.&lt;/p&gt;
&lt;h3 id=&quot;round-1&quot;&gt;Round 1&lt;/h3&gt;
&lt;p&gt;Practise this for &lt;strong&gt;10 minutes&lt;/strong&gt;. Use a timer.&lt;/p&gt;
&lt;p&gt;Pick a function, pick any parameter to that function, then follow these instructions to replace a single thing with a collection of things. &lt;strong&gt;The resulting code does not need to make sense nor be better&lt;/strong&gt;. You will throw your changes away at the end. Perform this move by paying close attention to the microsteps. Focus on precision and safety, not speed. Focus on finishing each step before starting the next one. If you finish refactoring your function, pick another one.&lt;/p&gt;
&lt;p&gt;When the timer signals that 10 minutes are up, consider reading your code, but don’t feel obliged to do that. Take a moment to recover. Throw away your changes, such as with &lt;code&gt;git reset --hard&lt;/code&gt;. Step away for a few minutes. Maybe even come back to this tomorrow.&lt;/p&gt;
&lt;h3 id=&quot;round-2&quot;&gt;Round 2&lt;/h3&gt;
&lt;p&gt;Repeat round 1 for 10 minutes. &lt;strong&gt;Pick the same function that you started with last time&lt;/strong&gt;, if you can remember it. Practise in the same way as before. If you finish refactoring one function, pick another one. Continue until you finish 10 minutes. Recover. Throw away your changes. Step away.&lt;/p&gt;
&lt;h3 id=&quot;rounds-3-and-4&quot;&gt;Rounds 3 and 4&lt;/h3&gt;
&lt;p&gt;Practise again for &lt;strong&gt;only 5 minutes&lt;/strong&gt; each time. Take a short break between rounds.&lt;/p&gt;
&lt;h3 id=&quot;rounds-5-and-up&quot;&gt;Rounds 5 and up&lt;/h3&gt;
&lt;p&gt;Practise as many times as you like for 5-15 minutes per round. Start at 5 minutes, then as that feels comfortable, try a longer session. Start anywhere in the code. Throw away your changes each time. Take a short break between rounds. &lt;strong&gt;Do this until you feel like nothing is changing&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;debrief&quot;&gt;Debrief&lt;/h3&gt;
&lt;p&gt;As you complete each practice round, &lt;strong&gt;become aware of how much conscious effort you need to bring to this work&lt;/strong&gt;. You might notice going more quickly, but &lt;strong&gt;I care more that you notice going &lt;em&gt;more easily&lt;/em&gt;, meaning with less effort&lt;/strong&gt;. Become aware of becoming more comfortable thinking ahead, remembering where you are in the steps, remembering what’s left to do, and taking shortcuts while remaining safe. With enough practice, you’ll feel confident doing this refactoring in an industrial-strength situation. More importantly, you’ll feel &lt;em&gt;almost no resistance&lt;/em&gt; to refactoring like this in an industrial strength situation. &lt;strong&gt;The lack of resistance signals beneficial chunking&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;future-work&quot;&gt;Future Work&lt;/h3&gt;
&lt;p&gt;Once you’ve done this with my sample drill, you can probably invent similar drills for other refactoring moves, like Replace Conditional with Polymorphism or Replace Inheritance with Delegation or Replace Action with Pub/Sub Event. Gradually you’ll feel more comfortable just working this way at your day job. Gradually &lt;strong&gt;you’ll take on bigger restructurings&lt;/strong&gt; by thinking of them as a sequence of safe, reversible moves that you can make steadily and confidently.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Refactoring benefits the programmer who develops habits that make refactoring effortless. You can achieve this by chunking at the level of nanosteps, then microsteps, then moves. If you do this, then you’ll see how to guide your system’s design to evolve safely and steadily. If you don’t, then you’ll likely remain the trap of wishing you could rewrite it, but never being able to justify that—at least not until a crisis hits. A little practice goes a long way to doing much better than that. &lt;strong&gt;Repetitive deliberate practice leads to chunking&lt;/strong&gt; leads to confidence leads to a lack of resistance &lt;strong&gt;leads to better results&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Wikipedia, &lt;a href=&quot;https://en.wikipedia.org/wiki/Chunking_(psychology)&quot;&gt;“Chunking (psychology)”&lt;/a&gt;. A reasonable overview of the concept, including how it relates to using working memory more efficiently.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.jbrains.ca/permalink/test-driven-development-as-pragmatic-deliberate-practice&quot;&gt;“Test-Driven Development as Pragmatic Deliberate Practice”&lt;/a&gt;. I see TDD as a pragmatic way to deeply understand modular design through deliberate practice.&lt;/p&gt;
&lt;p&gt;Andrew Hunt and Dave Thomas, &lt;a href=&quot;https://link.jbrains.ca/WNg8Se&quot;&gt;&lt;em&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/em&gt;&lt;/a&gt;. Still one of those classics that demands a place on every programmer’s bookshelf.&lt;/p&gt;
&lt;h1 id=&quot;attributions&quot;&gt;Attributions&lt;/h1&gt;
&lt;p&gt;The icons in this article came from &lt;a href=&quot;https://thenounproject.com&quot;&gt;The Noun Project&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;head with a target&lt;/strong&gt; by &lt;em&gt;Veremeya&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;paraphrase translate&lt;/strong&gt; by &lt;em&gt;Eucalyp&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;computing&lt;/strong&gt; by &lt;em&gt;ProSymbols&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 13 May 2020 12:30:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/breaking-through-your-refactoring-rut</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/breaking-through-your-refactoring-rut</guid>
        
        
        <category>Simple Design</category>
        
        <category>Microtechniques</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>You Don&apos;t Hate Mocks; You Hate Side-Effects</title>
        <description>&lt;p&gt;You don’t hate mocks; you hate side-effects.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; When a mock annoys you, it realizes its purpose, showing you where a side-effect is getting in your way. If you refactor away from the side-effect, then you eliminate the mock. The mock is a &lt;strong&gt;consequence of your pain&lt;/strong&gt;, not the cause of it. Please don’t blame the poor mock for doing its job.&lt;/p&gt;
&lt;h2 id=&quot;clarifying-terms&quot;&gt;Clarifying Terms&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/icons/noun_translate_1926172.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;Here, when I say &lt;em&gt;mock&lt;/em&gt; I specifically mean an &lt;em&gt;expectation&lt;/em&gt;, often implemented by library functions with names like &lt;code&gt;verify()&lt;/code&gt;, &lt;code&gt;expect().toHaveBeenCalled()&lt;/code&gt; and &lt;code&gt;should_receive&lt;/code&gt;. I don’t mean the general concept commonly known as “mock objects”, which I prefer to call &lt;em&gt;test doubles&lt;/em&gt;. For the rest of this article, &lt;strong&gt;I’ll use the word &lt;em&gt;mock&lt;/em&gt; to refer specifically to this narrower term&lt;/strong&gt;. If you don’t feel confident that you understand this distinction, then I recommend Martin Fowler’s classic &lt;a href=&quot;https://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;“Mocks Aren’t Stubs”&lt;/a&gt; as well as my &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/i-like-mocks&quot;&gt;“I Like Mocks, But I Distrust Spies”&lt;/a&gt; to illustrate some of the differences.&lt;/p&gt;
&lt;h2 id=&quot;sigh-clickbait&quot;&gt;“Sigh… Clickbait”&lt;/h2&gt;
&lt;p&gt;Yes, somewhat. Sorry. Marketing.&lt;/p&gt;
&lt;p&gt;If you prefer, think of this article as &lt;em&gt;On the nature of excessive function expectations and how they merely reflect an excess of side-effects&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;test-doubles-consequence-not-cause&quot;&gt;Test Doubles: Consequence, Not Cause&lt;/h2&gt;
&lt;p&gt;I don’t consider myself a member of any one school of TDD; I sampled them all and settled on a personal style. I lean towards the London school in that I don’t fear test doubles—I don’t consider them a thing to avoid. On the contrary, I value them as a design tool. (Read on.) By the same token, I don’t keep them for the sake of having them. As I’ll argue here, &lt;a href=&quot;/permalink/beyond-mock-objects&quot;&gt;certain design improvements have the side-effect (pun intended) of eliminating some test doubles&lt;/a&gt;. This means in particular that &lt;a href=&quot;https://www.tddstpau.li/&quot;&gt;I don’t view test doubles as a thing to either embrace nor avoid&lt;/a&gt;. I use them when I think in terms of side-effects, which I tend to do because of the Object-Oriented Programming influences around me during my formative years of learning about software design. Even though I embrace test doubles in my practice, &lt;strong&gt;I tend to &lt;em&gt;gradually&lt;/em&gt; refactor away from them&lt;/strong&gt; as I get features running, then later feel the urge to reduce mutability and apply the &lt;a href=&quot;https://dependency-inversion-principe.jbrains.ca&quot;&gt;Dependency Inversion Principle&lt;/a&gt; more aggressively. The presence or not of test doubles becomes a consequence of my approach, rather than a primary consideration in how I practise TDD.&lt;/p&gt;
&lt;p&gt;I considered myself a London school pupil while I was progressing through my Advanced Beginner stage of evolutionary design practice, on my way towards the Competent stage.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; I saw &lt;a href=&quot;https://www.amazon.com/Growing-Object-Oriented-Software-Addison-Wesley-Signature-ebook/dp/B002TIOYVW?crid=2KC04XG3QJSNW&amp;amp;dchild=1&amp;amp;keywords=growing+object-oriented+software%2C+guided+by+tests&amp;amp;qid=1630840586&amp;amp;sprefix=growing+object-o%2Caps%2C188&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=jbrains.ca-20&amp;amp;linkId=b267dfeae92f84b4695a5e77d23deb2a&amp;amp;language=en_US&amp;amp;ref_=as_li_ss_tl&quot;&gt;what Steve Freeman, Nat Pryce, and the rest of the London crowd were doing&lt;/a&gt;, I liked the direction they were going in, and I felt I could do what they were doing to achieve similar success in my designs, and so I chose to follow them for a while. Although I no longer consider myself a student of the London school—and I am certainly not any kind of &lt;em&gt;adherent&lt;/em&gt;—I’m happy to have spent several “semesters” there learning with the leaders I found there. I can test-drive in the London style when the situation calls for it and I teach the style because I find that &lt;strong&gt;it helps programmers feel more fully the pain of side-effects&lt;/strong&gt; so that they will sooner appreciate the &lt;a href=&quot;https://www.youtube.com/watch?v=eOYal8elnZk&quot;&gt;value of both immutability and pull unstable details up the call stack&lt;/a&gt;. I hope to make this concept appealing and practical, rather than confining it to the pages of textbooks. (They’re &lt;em&gt;really&lt;/em&gt; good textbooks!) I have noticed that &lt;strong&gt;struggling to tame test doubles tends to lead programmers towards deeply appreciating the value of immutability and abstraction&lt;/strong&gt;. It helps them embrace the Dependency Inversion Principle sooner, leading to designs with more-helpful abstractions that are generally more resilient to change, composed of smaller, more-recombinable parts.&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;Rather than avoid test doubles, many programmers benefit from overusing them in order to “make more real” the forces that increase/decrease the cost of changing code. I consider it a natural part of the learning process.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The rest of this article describes how this approach works in practice.&lt;/p&gt;
&lt;h2 id=&quot;you-could-try-using-integrated-tests-but&quot;&gt;You Could Try Using Integrated Tests, But…&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;I’ve written and spoken about this extensively since about 2003&lt;/a&gt;. Let me summarize my current thinking (as of early 2020), so that you don’t need to read everything that came before until you feel like it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Integrated tests, running larger portions of the system at once, make it more difficult to isolate the cause of behavior problems in code, so I prefer more-solitary (Fowler’s term) or more-focused (my term) tests.&lt;/li&gt;
&lt;li&gt;Integrated tests run larger portion of the system at once, so they seem particularly ill-suited to try to detect a specific side-effect in the code. They can do so only indirectly in a way that the writer understands but that readers tend not to. This seems especially wasteful when one could otherwise simply use an &lt;em&gt;expectation&lt;/em&gt; (a “mock”) to do exactly the same thing.&lt;/li&gt;
&lt;li&gt;If you replace side-effects with return values, then you simplify the nature of the corresponding tests. You can write more-focused tests without test doubles at all! Instead, you write straightforward tests with “assert equals”.&lt;/li&gt;
&lt;li&gt;Relying on integrated tests leads over time to more-tangled code, which makes it harder over time to write focused tests, which encourages relying more on integrated tests. This feedback loop increases overinvestment in tests, either by writing too many expensive tests or getting too-little value from the tests you write.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;programmers-arent-listening-to-the-mocks&quot;&gt;Programmers Aren’t Listening To the Mocks&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/icons/noun_deaf%20mute_3023646.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;I work with a handful of programmers each year who report having trouble with test doubles in general and with expectations in particular. Most often the trouble lies in two main areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The programmer doesn’t understand much about why to use test doubles, but since the project uses them, the programmer uses them. The programmer does the best they can to follow the local conventions, but ends up creating tangled messes in the tests that reflect tangled messes in the production code. They conclude that “test doubles are hard”.&lt;/li&gt;
&lt;li&gt;The programmer tries to practise TDD in order to improve their results, but succumbs to schedule pressure and chooses to copy/paste complicated test double usage patterns in their tests, rather than refactoring. The programmer understands vaguely that test doubles can help them produce “better” designs, but lacks the experience to refactor towards those better designs, and so gives in to the pressure to finish features (real or imagined), resulting in convoluted tests that they understand while writing but fail to understand months later while reading.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In both cases, the programmer doesn’t listen to the feedback that the excessive expectations are giving them. Sometimes they conclude that test doubles “are hard” or “don’t work”. Sometimes they conclude that they don’t (yet) understand how to listen to the feedback from their test doubles and they never quite feel confident enough to take the time to practise and learn. &lt;strong&gt;As a coach, I often (merely) provide the opportunity that those programmers need to practise and learn, even if I don’t teach them anything new about how to design effectively with test doubles!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;how-you-might-benefit-from-listening-to-those-expectations&quot;&gt;How You Might Benefit From Listening To Those Expectations&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/icons/noun_Listen_1821643.png&quot;&gt;&lt;/img&gt;I remember first learning about functional programming and read something vague about programming without side-effects. This instruction felt sensible, but useless, because I didn’t know how to start. I grew up learning object-oriented design as my primary way of thinking about modularity, so it felt perfectly natural for me to think in terms of side-effects. When I tried to understand what functional programming had to offer me, I tried to think differently, but couldn’t. (Even in 2020 I have trouble doing so.) I felt as though my head kept hitting a brick wall.&lt;/p&gt;
&lt;p&gt;As I experimented with refactoring away from side-effects, I gradually understood the relationship between side-effects and expectations. I gradually became comfortable refactoring away from side-effects, which helped me feel free to think directly in side-effects, then refactor away from them later. Accordingly, I stopped trying to force changes in how I think about modularity, which had the delightful effect of making it easier to think directly in terms of designs that push side-effects to the edges of the system, a style known as &lt;em&gt;functional core, imperative shell&lt;/em&gt;. Maybe one day I’ll think clearly and effortlessly directly in designs mostly devoid of side effects, but in the meantime, knowing how to refactor away from side-effects makes them temporary in my designs, so I don’t need to feel resistance to putting them there. When expectations start to “feel funny” in my tests, I know that a troublesome side-effect has settled in to the design, but since I know how to refactor away from them, I feel no anxiety about them and I feel little resistance to removing them.&lt;/p&gt;
&lt;h3 id=&quot;two-overall-strategies&quot;&gt;Two Overall Strategies&lt;/h3&gt;
&lt;p&gt;I see two general strategies for refactoring away from side-effects: replace the effect with a return value or replace the effect with an event. The first eliminates the effect while the second merely reduces it in size. Both strategies help in different situations. I tend towards the first of these when I can clearly see how to do it well and I tend towards the second of these when I can see how a group of side-effects relate to each other and truly represent implementations of the same underlying event handler.&lt;/p&gt;
&lt;p&gt;One common pattern for replacing the effect with a return value concerns the Collecting Parameter pattern: you pass a list into a function which might add values to that list. I can replace this mechanically with returning a list of values to add, then letting the invoker add those items to the list that it would otherwise pass into this function. This refactoring moves to design in the direction of using a common functional programming library function often known as &lt;code&gt;concat&lt;/code&gt;, which takes a lists of lists and puts their elements all together into a single list. Now, of course, you don’t need mocks to test a function that uses a Collecting Parameter, because you could simply create a collection in your tests and let the function append to that collection, but you could also apply the general principle of this refactoring to more-generic side effects than appending items to a list. I intend to write this as a more-detailed example in a future article, although I imagine you could find several examples right now from other authors who got there well before I did. &lt;strong&gt;We always have the option of replacing a side-effect with returning a value that represents the effect, as long as we can instruct the clients to interpret that value as a command to execute.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Regarding a group of related side-effects, if I notice such a group that always happen at the same time in the code, then I see them as all responses to the same event. From here, I turn them into literal implementations of the same event interface (first lambdas, then maybe eventually as implementations of the same interface), then &lt;a href=&quot;https://dependency-inversion-principle.jbrains.ca&quot;&gt;invert the dependency&lt;/a&gt; so that these implementors subscribe to the event, rather than the broadcaster knowing exactly which actions to perform. This makes the design more flexible, simplifies the test, and makes me aware of previously-unnoticed tangles among the various actions/responses/subscribers, if any exist. This relates in a significantly more-recombinable design &lt;strong&gt;We always have the option of replacing a group of related side-effects with firing a single event whose subscribers are those various side-effects, which often helps us keep those side-effects from becoming dangerously entangled with one another.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;thank-you-excessive-expectations&quot;&gt;Thank You, Excessive Expectations!&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/icons/noun_canary_2535720.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;I think of excessive expectations as the canary in the coal mine: a helpful alarm signal worthy of my gratitude. Thank you, excessive expectations, for alerting me to a design problem before it spirals out of control!&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/beyond-mock-objects&quot;&gt;“Beyond Mock Objects”&lt;/a&gt;. A more-detailed example of one way to refactor that reduces the need for test doubles.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;OK, maybe you don’t hate &lt;em&gt;anything&lt;/em&gt;, but some programmers do. I’m using the phrase a bit provocatively here. If you prefer, substitute the opening “You don’t mistrust mocks; you mistrust side-effects”. It has less punch, but it’s likely more accurate. Sorry.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;These terms come from the Dreyfus Model of Skill Acquisition. It’s just a model; it’s not a law. These terms help me succinctly describe different stages of learning that people commonly encounter. I don’t use the model for anything more sophisticated than that. I find the names of the stages unnecessarily judgmental, but since they have established meaning, I continue to use them.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sat, 02 May 2020 11:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/you-dont-hate-mocks-you-hate-side-effects</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/you-dont-hate-mocks-you-hate-side-effects</guid>
        
        
        <category>Test Doubles</category>
        
        <category>Simple Design</category>
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Choosing Tools for Test Doubles</title>
        <description>&lt;p&gt;When I teach evolutionary design, participants still often ask me which tools they ought to use to introduce test doubles into their projects. Yes, I nudge them gently in the direction of focusing on principles and techniques and away from fixating on tools, but &lt;a href=&quot;#references&quot;&gt;they still need a place to start&lt;/a&gt;. This question often comes in the following form:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do you favor hand-rolling test doubles or using a library (like NSubstitute, Mockito, or rspec-mock)?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I choose the option that balances &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;removing duplication&lt;/a&gt; with requiring the least effort, just as I make a large number of my design decisions. The question of test doubles here doesn’t change my general approach. I use a library if I can trust it and if it will reduce the cost of changing code over time.&lt;/p&gt;
&lt;h2 id=&quot;a-tie-breaker-arbitrary-personal-preference&quot;&gt;A Tie-Breaker: Arbitrary Personal Preference&lt;/h2&gt;
&lt;p&gt;I like the syntactic uniformity of using a library like JMock or NSubstitute. I read code more easily when I can anticipate the syntax it uses to express an idea. In particular, I find it easier to &lt;em&gt;skim&lt;/em&gt; when I correctly anticipate the syntax it uses to express an idea. &lt;strong&gt;I prefer making code easier to skim in general, since that reduces the effort one needs to read and mentally process it.&lt;/strong&gt; This nudges me towards uniformity when I feel no other significant need for variety. Therefore, if I would use a test doubles library somewhere in the project, then I would tend to prefer to use it everywhere in the project. &lt;strong&gt;I freely admit this as an arbitrary personal preference&lt;/strong&gt; and I consider it my responsibility not to advocate for my personal preference in situations where there might exist objectively more-appropriate or less-appropriate choices. Otherwise, all else equal, I’d use the test double library everywhere.&lt;/p&gt;
&lt;p&gt;This raises an obvious question: which contexts might lead to more-objectively appropriate choices? I offer two as examples: stubs in Java and expectations everywhere.&lt;/p&gt;
&lt;h2 id=&quot;example-java-lambda-expressions-and-stubs&quot;&gt;Example: Java, Lambda Expressions, and Stubs&lt;/h2&gt;
&lt;p&gt;Java 8 added lambda expressions and decided to make one-method interfaces and lambda expressions interchangeable. This means, for example, that a function accepting a parameter that’s a one-method interface can also accept a lambda expression with the same &lt;em&gt;shape&lt;/em&gt; (same input parameter types and same return value type). The compile-time type checker doesn’t mind. I can choose whichever syntax better fits the situation: a one-method interface or a lambda expression. This opens up an opportunity for conciseness and flexibility that hadn’t existed previously and this prompted me to go against my arbitrary personal preference.&lt;/p&gt;
&lt;h3 id=&quot;before&quot;&gt;Before…&lt;/h3&gt;
&lt;p&gt;Before Java 8, a hand-rolled stub required an anonymous implementation of an interface with non-trivial extra syntax. I found it easy to justify using a test double library in this situation, because it removed duplicate meaningless (boilerplate) syntax.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void productNotFound() throws Exception {
    Catalog catalog = new Catalog() {
        @Override
        public Option&amp;lt;Price&amp;gt; findPrice(String barcode) {
            return Option.none();
        }
    };
    
    SellOneItemController controller = new SellOneItemController(catalog);
    
    String responseText = controller.handleRequest(&amp;quot;99999&amp;quot;);
    
    Assertions.assertEquals(&amp;quot;Product not found: 99999&amp;quot;, responseText);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, I &lt;em&gt;understand&lt;/em&gt; it, but I have a little trouble &lt;em&gt;skimming&lt;/em&gt; it. By using a test double library, I feel less resistance trying to read the test at a glance. And yes, it feels like a perfectly surmountable obstacle in this small example, but if I add enough pebbles to the basket you’re carrying, you’ll eventually no longer manage to carry it.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;private final Catalog catalog = mock(Catalog.class);

@Test
public void productNotFound() throws Exception {
    when(catalog.findPrice()).thenReturn(Option.none());
    SellOneItemController controller = new SellOneItemController(catalog);
    
    String responseText = controller.handleRequest(&amp;quot;99999&amp;quot;);
    
    Assertions.assertEquals(&amp;quot;Product not found: 99999&amp;quot;, responseText);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I find this more concise: I skim it more easily. This version hides irrelevant details, namely the syntax of overriding a method in Java. I judge &lt;code&gt;when&lt;/code&gt; and &lt;code&gt;thenReturn&lt;/code&gt; to better express the intent of the object. All these nudge me in the direction of using the test double library, which aligns with my arbitrary personal preference, which I like.&lt;/p&gt;
&lt;h3 id=&quot;after&quot;&gt;…After&lt;/h3&gt;
&lt;p&gt;I get the best of both worlds by taking advantage of interchanging lambda expressions with one-method interfaces, resulting in syntax that hides irrelevant details without requiring a library.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void productNotFound() throws Exception {
    Catalog catalog = barcode -&amp;gt; Option.none();
    SellOneItemController controller = new SellOneItemController(catalog);
    
    String responseText = controller.handleRequest(&amp;quot;99999&amp;quot;);
    
    Assertions.assertEquals(&amp;quot;Product not found: 99999&amp;quot;, responseText);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t consider this a &lt;em&gt;clear&lt;/em&gt; improvement, but I certainly feel open to it. I skim it reasonably well, but when reading it for the first time, I might find the lambda expression a bit jarring: it hides irrelevant details well, but it might hide relevant details, too. This version hides the fact that &lt;code&gt;Catalog&lt;/code&gt; only does &lt;code&gt;findPrice()&lt;/code&gt;, at least for now. I would feel &lt;em&gt;much better&lt;/em&gt; if I renamed the interface to &lt;code&gt;FindPrice&lt;/code&gt; and let go of the artificial preference for a noun over a verb. (“Nouns are more object-y!”)&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void productNotFound() throws Exception {
    FindPrice findPrice = barcode -&amp;gt; Option.none();
    SellOneItemController controller = new SellOneItemController(findPrice);
    
    String responseText = controller.handleRequest(&amp;quot;99999&amp;quot;);
    
    Assertions.assertEquals(&amp;quot;Product not found: 99999&amp;quot;, responseText);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I quite like this: easy to skim, &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;hides irrelevant details&lt;/a&gt;, &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;expresses intent&lt;/a&gt;. It likely looks strange to someone not familiar with the functional programming style of passing lambda expressions around, but then this might provide to the reader a gateway to learning about function programming. I wouldn’t consider that a primary goal, but as a pleasant side-effect, I might like it.&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;I could happily hand-roll stubs in languages with concise-enough syntax that the test double library’s uniformity doesn’t express intent significantly better than the language’s built-in features do. I might even prefer it.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;expectations-i-probably-always-prefer-a-library&quot;&gt;Expectations: I Probably Always Prefer a Library&lt;/h2&gt;
&lt;p&gt;Writing method expectations by hand means duplicating code, &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;which I generally prefer to avoid&lt;/a&gt;. For this reason, I routinely use a test double library—even a library like JMock whose syntax not everyone likes. On average I don’t see the value in repeating this kind of pattern in my code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a field to check whether the subject under test invokes the expected method. Remember to initialize it to &lt;code&gt;false&lt;/code&gt; or empty or whichever value represents “not yet invoked”.&lt;/li&gt;
&lt;li&gt;Maybe add details to that field to store the parameters that the expected method received, so that I can check them.&lt;/li&gt;
&lt;li&gt;Add one or more assertions to verify the expectation. Should we fail fast, checking the parameters at the moment the test invokes the expectation? Should we respect the traditional sequence of a test and store those parameters so that we can check them at the end? We have to decide and we should probably do it consistently.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Worse, in some languages and situations I might implement this differently, depending on how much of the method expectation I need to check.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If I don’t need to check the parameters, then I use a boolean field called something like &lt;code&gt;blahblahWasInvoked&lt;/code&gt;, but if I do check the parameters, then I use a Maybe List of arguments passed.&lt;/li&gt;
&lt;li&gt;If the subject might invoke the expected method multiple times, I replace the boolean/Maybe with an explicit collection.&lt;/li&gt;
&lt;li&gt;In some languages, I use old-fashioned Log String pattern because it suffices and requires less-involved syntax.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This already feels like too many decisions. Worse, the kind of tiny decisions that too often devolve into bikeshedding. Meh. A uniform syntax with enough flexibility pushes all that nonsense to the side. Moreover, I’d rather implement the concept once, uniformly, and &lt;em&gt;correctly&lt;/em&gt;, then hide the details in a nice reusable library. We programmers get into trouble when our tests become complicated enough that we might get them wrong. I’ve seen it even in the last five years that a programmer hand-rolled an expectation, leading to a test that could never fail. (It checked the parameters to the expected method, but not whether anything ever invoked the method.) Everyone who hand-rolls expectations gets this wrong at least once, &lt;strong&gt;including me&lt;/strong&gt;. To avoid this mistake, we either delegate this behavior to something we trust or we end up wanting to test the tests. Who tests the tests? And who tests the tests that test the tests?! Let’s not go there.&lt;/p&gt;
&lt;p&gt;As regards method expectations, using a test double library represents an almost-certain win for me compared to hand-rolling them, so I default to using a library until I see a compelling reason to do otherwise. I don’t mean that as code for “don’t ever do it”: I hand-rolled a method expectation during a demonstration where I didn’t plan on needing one, judged that the audience would become confused by trying to add a library to the project, and realized that I wasn’t likely to need a second expectation. Hand-rolling the expectation felt like the path of least resistance in the moment. Here, I found myself in a very peculiar situation. &lt;strong&gt;I don’t remember the last time that, in an industrial-strength, professional project situation, I preferred hand-rolling method expectations to using a library.&lt;/strong&gt; In the worst case, I could imagine hand-rolling the first two method expectations, then invoking the Rule of Three to refactor towards using a library.&lt;/p&gt;
&lt;h2 id=&quot;that-leaves-me-one-key-question&quot;&gt;That Leaves Me One Key Question&lt;/h2&gt;
&lt;p&gt;Why do some of my peers—most of whom I respect—insist on advocating loudly against test-double libraries and in favor of hand-rolling? I don’t think I understood this until recently. This question reminds me of the &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest&quot;&gt;long-time mystery of why Corey Haines and others insist on enumerating the four elements of simple design in the wrong order&lt;/a&gt;. If I could solve that mystery, then maybe I could solve this one. The act of drafting this article led me to do exactly that.&lt;/p&gt;
&lt;h2 id=&quot;one-pattern-ive-noticed&quot;&gt;One Pattern I’ve Noticed&lt;/h2&gt;
&lt;p&gt;I’ve noticed programmers who advocate hand-rolling all their test doubles all the time always. Such absolute rules tend to make me nervous, although I can think of two reasonable explanations for this advice. First, as a Novice Rule, it might help the programmer in the usual Novice Rule ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remove an element where they need to exercise judgment while they focus on correctly executing the technique.&lt;/li&gt;
&lt;li&gt;Defer consideration of a higher-level concern while they focus on understanding the lower-level concern. They will more-easily consider the higher-level concern when they’ve “chunked” the ideas at the lower level.&lt;/li&gt;
&lt;li&gt;Provide clear direction in order to reduce resistance towards starting to use the technique.&lt;/li&gt;
&lt;li&gt;Provide a small, recurring sense of completion with just-enough challenge.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not everyone likes the Novice Rule approach, but it has helped enough people often enough to earn a place in my bag of tricks. More significantly, however, I have noticed a pattern in programmers who advocate hand-rolling all their test doubles all the time always which has nothing to do with Novice Rules nor any other pedagogic technique. For those programmers, they advocate hand-rolling test doubles as a side-effect of a more-significant pattern in how they design.&lt;/p&gt;
&lt;h3 id=&quot;warning-strong-generalizations-ahead&quot;&gt;Warning: Strong Generalizations Ahead&lt;/h3&gt;
&lt;p&gt;Forgive me.&lt;/p&gt;
&lt;p&gt;Let me use the phrase “object-oriented programmer” to mean someone who broadly thinks natively in terms of object-oriented design terms, but in the best possible way. Think Alan Kay and his famous advocacy for thinking about encapsulation and message-passing, rather than the pejorative sense of a programmer who uses objects as arbitrary collections of global functions manipulating global variables wearing bow ties as singletons and nakedly-mutable, arguably-cohesive &lt;code&gt;struct&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;Let me also use the phrase “functional programmer” to mean someone who broadly thinks natively in terms of functional programming design terms, but in the best possible way. Think of a strong bias towards immutability and pushing state to the edges of the design, rather than the pejorative sense of a programmer who wields abstractions with arcane names as a cudgel to beat poor object-oriented programmers around the head with.&lt;/p&gt;
&lt;p&gt;Object-oriented programmers and functional programmers tame side effects differently, resulting in object-oriented programmers using expectations much more often than functional programmers. Functional programmers invert dependencies more aggressively than object-oriented programmers. who weaken some of those dependencies as an intermediate step towards inverting them. This results in functional programmers having an accidental bias towards hand-rolling test doubles &lt;strong&gt;because they actually do what I do, but since they almost never use expectations, they never invoke the “remove duplication” reason to prefer test double libraries over hand-rolling&lt;/strong&gt;. Functional programmers rarely use expectations &lt;em&gt;and&lt;/em&gt; they work in languages with concise syntax for lambda expressions, so &lt;em&gt;by coincidence&lt;/em&gt; they find it very comfortable to hand-roll (almost all) their test doubles.&lt;/p&gt;
&lt;p&gt;Mystery solved.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I tend very strongly to use test double libraries for method expectations, in order to remove duplication. I need a compelling reason to hand-roll method expectations.&lt;/li&gt;
&lt;li&gt;I freely both hand-roll and use test double libraries for stubs, depending on the context. I fall back on more-general design principles to make this decision in a specific situation.&lt;/li&gt;
&lt;li&gt;I believe that programmers who advocate loudly for hand-rolling test doubles all the time just happen to work most often in a style and a context where I would happily hand-roll most of my test doubles anyway, so I view their advice as a special case of my own.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/jmock-v-mockito-but-not-to-the-death&quot;&gt;“JMock v. Mockito, But Not to the Death”&lt;/a&gt;. One case where the choice of tool depends on my conscious intent in addition to accidents of history and arbitrary personal preference.&lt;/p&gt;
&lt;p&gt;Chip Heath and Dan Heath, &lt;a href=&quot;https://link.jbrains.ca/TeSr30&quot;&gt;&lt;em&gt;Switch&lt;/em&gt;&lt;/a&gt;. A manual on guiding people to changing their behavior, which includes a chapter on “scripting the critical first steps”—that is, describing a clear way to start.&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Apr 2020 10:25:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/choosing-test-for-test-doubles</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/choosing-test-for-test-doubles</guid>
        
        
        <category>Simple Design</category>
        
        <category>Test Doubles</category>
        
      </item>
    
      <item>
        <title>Where the Hell Is My Port?! An Adventure in Elm</title>
        <description>&lt;p&gt;If you add a &lt;a href=&quot;https://guide.elm-lang.org/interop/ports.html&quot;&gt;&lt;em&gt;port&lt;/em&gt; in Elm code&lt;/a&gt;, then you need to &lt;em&gt;use&lt;/em&gt; that port in your Elm code, otherwise the generated Javascript might not even know that your Elm code uses ports at all. As I learn Elm and become accustomed to its compiler’s wonderfully-detailed error messages, encountering error messages like this suddenly feel jarring and I even have trouble understanding them for a moment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TypeError: app.ports is undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I saw this message in the browser’s Javascript console when I tried to add the first port to my Elm application, but hadn’t yet written any Elm code that uses the port. I learned later that &lt;code&gt;elm make&lt;/code&gt; hadn’t generated any Javascript code related to ports, because none of my ports &lt;em&gt;did&lt;/em&gt; anything. Specifically, this means that the Elm compiler didn’t generate a &lt;code&gt;ports&lt;/code&gt; property for the &lt;code&gt;app&lt;/code&gt; object that &lt;code&gt;Elm.Main.init(...)&lt;/code&gt; returns. Therefore, &lt;strong&gt;when you add a port to Elm code, if you don’t send any messages to that port, then you cannot assume that the compiled Javascript code will include code for that port&lt;/strong&gt;. In particular, &lt;strong&gt;if your Elm code doesn’t write to any of your ports, then you cannot assume that the compiled Javascript code will include any code about ports at all&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you’ve found this article because you got stuck writing your first port in an Elm application, then I hope this suffices to get you unstuck. If so, I’m glad! If you’re interested in how I got here, then read on.&lt;/p&gt;
&lt;h2 id=&quot;how-did-i-get-here&quot;&gt;How Did I Get Here?&lt;/h2&gt;
&lt;p&gt;I typically like to write code incrementally, because that feels safer to me. I like to take small steps and check my work frequently, especially in unfamiliar environments. I don’t know Elm very well yet and I certainly don’t feel like I can write Elm fluently, so I take smaller steps when I build something in Elm. In particular, I’d never used &lt;em&gt;ports&lt;/em&gt; before, so I chose to take even smaller steps to write my first port. Sadly, I fell into a well-meaning trap: I expected there to be code that the Elm compiler helpfully optimized out of existence.&lt;/p&gt;
&lt;h3 id=&quot;the-steps-that-led-me-here&quot;&gt;The Steps That Led Me Here&lt;/h3&gt;
&lt;p&gt;I’m rebuilding a simple countdown timer in Elm. I’ve previously written one in Javascript to use in &lt;a href=&quot;https://training.jbrains.ca&quot;&gt;my training classes&lt;/a&gt; which replaces &lt;a href=&quot;https://apps.apple.com/us/app/howler-pro/id434985132&quot;&gt;the one that I liked to use on Mac OS&lt;/a&gt; before I switched to Linux. I chose to rebuild this in Elm, because I like that I can practise evolutionary design in a functional programming language while remaining in the familiar environment of HTML, Javascript, and the browser. &lt;a href=&quot;https://github.com/jbrains/countdown-timer-elm/tree/0c3e6a3615dd5c4ff1bd6dc287fb8001e964bac2&quot;&gt;I’ve built the basic operations of the timer&lt;/a&gt; (ticking, pausing, resuming, setting the time) and now it’s time to start playing sounds as the timer expires. These sounds provide both a convenient and fun way to warn my training class participants that they should pause their work, get things out of their head, and prepare for the next part of the course. They mostly seem to enjoy the funny sounds.&lt;/p&gt;
&lt;p&gt;When I looked for examples of playing sounds in Elm, I only found code that generates an HTML &lt;code&gt;audio&lt;/code&gt; tag and uses a standard in-browser audio player with start/stop buttons and the like. Instead, I want to play various sounds directly in response to a “tick” event. Since I didn’t know what else to do, I retreated what I’d previously built: play the sound in Javascript code. In order to invoke Javascript code from Elm, I need to use &lt;em&gt;ports&lt;/em&gt;, which gives me something new to learn. I read the &lt;a href=&quot;https://guide.elm-lang.org/interop/&quot;&gt;Elm guide’s section on JavaScript Interop&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since I wanted to work incrementally, I chose this strategy:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Add a port to the Elm code, but don’t send any messages to it yet.&lt;/li&gt;
&lt;li&gt;Subscribe to that port in the Javascript code.&lt;/li&gt;
&lt;li&gt;Check that the Elm and Javascript code are “wired together” correctly before even trying to send messages from Elm to the port.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I chose this approach based on a couple of decades of experience working in interpreted languages (Javascript, Ruby, Python) where syntax errors are common. I’ve wasted significant energy trying to write correct code and then hunting down strange errors only to find out that I’d made some elementary mistake early on and my code was never going to work. I see this mostly as a special case of the general principle &lt;strong&gt;if you’re not sure that you can write it correctly, then write less of it, so that when you fail, you have fewer places to look for the mistake&lt;/strong&gt;. Most of the time, this approach helps me not only avoid chasing the wrong mistake but also slowly build up a clearer picture of the unfamiliar environment in which I find myself, since I learn smaller parts of the environment in more detail as I go. This time, sadly, it caused me to waste more energy, not less.&lt;/p&gt;
&lt;h3 id=&quot;how-to-correctly-add-your-first-port-to-an-elm-application&quot;&gt;How To (Correctly) Add Your First Port To An Elm Application&lt;/h3&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Mark your main module as a &lt;code&gt;port module&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add a port.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the new port by sending a message to it from at least one branch of your application’s &lt;code&gt;update&lt;/code&gt; function&lt;/strong&gt;. (This is the step that I missed the first time.)&lt;/li&gt;
&lt;li&gt;Build your Elm code, generating new Javascript.&lt;/li&gt;
&lt;li&gt;Try to subscribe to the new port in the Javascript code that embeds and runs the Elm application.&lt;/li&gt;
&lt;li&gt;Reload your Elm application client Javascript code in a browser and look in the console for Javascript errors in the code that runs the Elm application. There should be no new error messages related to ports.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From this point, it’s safe for you to add more ports and use them. If you skipped the “send a message to the new port” step for your second port, then you’d see a Javascript error telling you that that port name is undefined inside the Javascript object corresponding to the Elm application. &lt;strong&gt;If you don’t send any messages to a port in Elm, then the corresponding Javascript code won’t know about that port.&lt;/strong&gt; Worse, &lt;strong&gt;if you don’t send any messages to any of your ports in Elm, then the corresponding Javascript code won’t about about ports at all!&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;a-contract-failure&quot;&gt;A Contract Failure&lt;/h3&gt;
&lt;p&gt;I interpret this mistake as a contract failure. I guessed an aspect the contract of the Elm compiler and got it wrong: I assumed that the generated Javascript code would contain a reference to ports because I’d marked the module as a “port module”. (Why does one need to do this, then? Please add a comment if you know.) If I’d known the Elm compiler better, then I might have guessed which specific aspect of the Elm compiler’s contract I’d got wrong, but since I just didn’t know, I considered that a waste of my energy. Instead, I immediately asked people who were more likely to guess better than I would. Sure enough, they guessed quite quickly that the Elm compiler eliminated “dead code”, a part of the contract that I did not know about. Although learning this part of the contract this way annoyed me in the moment, it didn’t cost me too much &lt;em&gt;and&lt;/em&gt; it has left enough of an impression that I’m likely to remember it for a while. &lt;strong&gt;I’m writing this now in order to document this aspect of the contract of the Elm compiler so that other programmers learning Elm might more easily get past this difference of understanding.&lt;/strong&gt; It’s the least I can do. I intend to contribute some text to the Elm guide right after I publish this.&lt;/p&gt;
&lt;h3 id=&quot;an-example-would-be-handy-right-now&quot;&gt;An Example Would Be Handy Right Now&lt;/h3&gt;
&lt;p&gt;I started with an Elm application that runs a singleton countdown timer. It has two modules: &lt;code&gt;Main&lt;/code&gt; and &lt;code&gt;Timer&lt;/code&gt;. The &lt;code&gt;Main&lt;/code&gt; module exposes &lt;code&gt;Timer&lt;/code&gt; to the world through a user interface. I use Jekyll in order to run the application with an embedded web server, avoiding relative paths to link the HTML page to the Javascript library that &lt;code&gt;elm make&lt;/code&gt; generates. If you have the energy to show me a way to achieve the same thing without Jekyll, then I’m happy to see it. &lt;a href=&quot;https://github.com/jbrains/countdown-timer-elm/pulls&quot;&gt;Please submit a pull request!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, I added a port to the Elm code without writing any messages to it yet. This requires two steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Mark the module with &lt;code&gt;port module&lt;/code&gt; instead of merely &lt;code&gt;module&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Define a &lt;code&gt;port&lt;/code&gt; as a function that turns some message payload into a &lt;em&gt;command&lt;/em&gt; value of type &lt;code&gt;Cmd unusedType&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For my first port, I chose one without payload, so the input type is &lt;code&gt;()&lt;/code&gt; (unit/void/nothing). The return type is &lt;code&gt;Cmd unusedType&lt;/code&gt;, and not &lt;code&gt;Cmd Msg&lt;/code&gt;. The Elm guide (as of the time of writing this article) describes this type as &lt;code&gt;Cmd msg&lt;/code&gt; with a lowercase &lt;code&gt;msg&lt;/code&gt;, which I misread the first time as &lt;code&gt;Cmd Msg&lt;/code&gt;. This led to a few minutes of confusion over an unexpected compile error.&lt;/p&gt;
&lt;pre class=&quot;elm&quot;&gt;&lt;code&gt;Detected problems in 1 module.
-- BAD PORT ------------------------------------------------------- src/Main.elm

The `ping` port cannot send any messages to the `update` function.

14| port ping : () -&amp;gt; Cmd Msg
         ^^^^
It must produce a (Cmd msg) type. Notice the lower case `msg` type variable. The
command will trigger some JS code, but it will not send anything particular back
to Elm.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t yet know why calling this type &lt;code&gt;Cmd msg&lt;/code&gt; expresses intent better than, say, &lt;code&gt;Cmd someArbitraryType&lt;/code&gt;, so I chose &lt;code&gt;Cmd unusedType&lt;/code&gt; &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;to more-clearly express the role, if not yet the intent&lt;/a&gt;. Please add a comment if you can describe the intent of this type parameter.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jbrains/countdown-timer-elm/tree/failure-when-adding-a-port&quot;&gt;If I subscribed to this new port in my HTML page &lt;em&gt;now&lt;/em&gt;&lt;/a&gt;, then the Elm compiler would not have generated any ports-related code (the compiler considers it &lt;em&gt;dead code&lt;/em&gt;), leading to the error message that originally prompted me to write this article. Instead, &lt;a href=&quot;https://github.com/jbrains/countdown-timer-elm/blob/try-adding-a-simple-port/elm/src/Main.elm#L73-L83&quot;&gt;I need to add code to at least one branch of the &lt;code&gt;update&lt;/code&gt; function to send a message to this new port&lt;/a&gt;. I decided to send a message when the timer &lt;em&gt;expires&lt;/em&gt; (meaning when it ticks down to no time remaining). To see this run, I watch the Javascript console in my browser, waiting for the timer to tick down to 0 seconds, at which point I see a single &lt;code&gt;PING&lt;/code&gt; message in the console. By this time I had a port working end to end and could resume trying to add the features that I cared about: playing a “warning” sound each second once the timer reaches 10 seconds remaining, then an “expired” sound once the timer expires.&lt;/p&gt;
&lt;p&gt;If you’ve become stuck trying to write your first port in an Elm application, then I hope this helped you fix the problem, understand how you got there, and helps you avoid the problem in the future.&lt;/p&gt;
</description>
        <pubDate>Thu, 30 Jan 2020 16:30:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/where-the-hell-is-my-port-an-adventure-in-elm</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/where-the-hell-is-my-port-an-adventure-in-elm</guid>
        
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Emerging Implementations of An Emerging Interface: An Example</title>
        <description>&lt;p&gt;How do object hierarchies evolve? Many programmers struggle with this question. Mostly, they want to know how object hierarchies can evolve &lt;em&gt;safely and sensibly&lt;/em&gt;! They have a picture in their mind that TDD is only safe in the hands of programmers with excellent design sense, but &lt;a href=&quot;https://tdd.training&quot;&gt;I believe that anyone can learn these skills with a combination of simple guidelines and guided practice.&lt;/a&gt; It would be nice to have more examples. I have stumbled upon one that I’d like to share with you.&lt;/p&gt;
&lt;p&gt;I’m refactoring some legacy code as part of my &lt;a href=&quot;https://surviving-legacy-code.jbrains.ca&quot;&gt;Surviving Legacy Code online course&lt;/a&gt;. In the process of using what I call the Mail Forwarding Technique, I came across an interesting little pattern, which led to significant results, one after another.&lt;/p&gt;
&lt;h1 id=&quot;the-situation&quot;&gt;The Situation&lt;/h1&gt;
&lt;div class=&quot;aside&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;I’m working on the Java version of this code base, and for now, I’ve chosen to restrict the legacy code to Java 6 level. This might explain some strange-looking decisions not to use more-modern libraries and language features.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I am extracting some behavior from a legacy class (&lt;code&gt;Game&lt;/code&gt;) that has exposed package-level fields to clients. For teaching purposes, I have adopted the constraint of keeping those fields backwards compatible (and their state up to date) until I can decide when I can safely hide them from clients. If you’ve been to a Code Retreat, then you understand the idea of volunteering to constrain yourself during practice.&lt;/p&gt;
&lt;p&gt;I am moving this behavior into a new class in the Happy Zone which I will call &lt;code&gt;GameEngine&lt;/code&gt;, which runs the game once it has started. The fields at issue hold the &lt;em&gt;questions&lt;/em&gt; that players ask each other during the game—think of a game like Trivial Pursuit. The legacy &lt;code&gt;Game&lt;/code&gt; has a few fields representing the list of questions in each of four categories (Pop, Science, Sports, Rock) and it consumes each question as we ask it, so that we don’t ask it twice. If you can believe it, &lt;code&gt;Game&lt;/code&gt; uses &lt;code&gt;LinkedList&lt;/code&gt; for this purpose &lt;em&gt;specifically so that it can use &lt;code&gt;removeFirst()&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;figure class=&quot;smaller&quot;&gt;
&lt;img src=&quot;https://media.giphy.com/media/1dNLLlpEUbeD8peO4e/giphy.gif&quot; /&gt;
&lt;/figure&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package com.adaptionsoft.games.uglytrivia;
[...]
public class Game implements UpdateLegacyGame {
[...]
    /*
     * BEGIN Legacy fields. Maintain backwards compatibility
     * at all costs until 2021-06-30.
     */
    LinkedList popQuestions = new LinkedList();
    LinkedList scienceQuestions = new LinkedList();
    LinkedList sportsQuestions = new LinkedList();
    LinkedList rockQuestions = new LinkedList();
[...]
}&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;explanation&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;The &lt;em&gt;Universal Architecture&lt;/em&gt; is my way of describing how to organize systems to maximize healthy dependencies. It is an abstraction compatible with the Onion Architecture, the Hexagonal Architecture, and Ports and Adapters. The &lt;em&gt;Happy Zone&lt;/em&gt; is the region of the code that we can easily check with only microtests running entirely in memory. Rescuing legacy code involves breaking dependencies in order to be able to move code into the Happy Zone, where code is generally happier to live.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I want the new &lt;code&gt;GameEngine&lt;/code&gt; to manage the state of the new &lt;code&gt;QuestionDeck&lt;/code&gt; (the set of collections of questions in the various categories, which corresponds to the legacy fields), but I need the legacy &lt;code&gt;Game&lt;/code&gt; to mirror changes to the &lt;code&gt;QuestionDeck&lt;/code&gt; until I can safely remove those legacy fields. For this, I introduce the interface &lt;code&gt;UpdateLegacyGame&lt;/code&gt; (whose &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names&quot;&gt;name I will improve later&lt;/a&gt;) which the legacy &lt;code&gt;Game&lt;/code&gt; implements so that &lt;code&gt;GameEngine&lt;/code&gt; can update the legacy game state without depending directly on legacy code. The legacy code will be able to delegate some of its behavior to new modules in the Happy Zone while keeping its legacy state up to date. It then becomes easier to microtest the extracted behavior.&lt;/p&gt;
&lt;h1 id=&quot;leading-up-to-the-moment&quot;&gt;Leading Up To the Moment&lt;/h1&gt;
&lt;p&gt;After starting to move the behavior into the Happy Zone, I notice that I will have some trouble writing succinct microtests for this behavior. I can already see &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/beyond-mock-objects&quot;&gt;all the test doubles (mock objects) that I’m going to need&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia;

import ca.jbrains.trivia.legacy.LegacyAskQuestion;
import ca.jbrains.trivia.legacy.UpdateLegacyGame;

public class GameEngine {
    private final UpdateLegacyGame updateLegacyGame;
    private final QuestionDeck questionDeck;

    public GameEngine(
            final UpdateLegacyGame updateLegacyGame,
            final QuestionDeck questionDeck) {

        this.updateLegacyGame = updateLegacyGame;
        this.questionDeck = questionDeck;
    }

    public void askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) {
        final String nextQuestionInCategory = questionDeck.getNextQuestionInCategory(category);
        askQuestion.askQuestion(nextQuestionInCategory);
        questionDeck.consumeNextQuestionInCategory(category);
        updateLegacyGame.updateQuestionDeckFields(questionDeck.asLegacyQuestionDeck());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can demonstrate the emerging problem by looking at the microtest that I have so far.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia.legacy.test;

import ca.jbrains.trivia.Category;
import ca.jbrains.trivia.GameEngine;
import ca.jbrains.trivia.QuestionDeck;
import ca.jbrains.trivia.legacy.LegacyAskQuestion;
import ca.jbrains.trivia.legacy.LegacyQuestionDeck;
import ca.jbrains.trivia.legacy.UpdateLegacyGame;
import io.vavr.collection.HashMap;
import io.vavr.collection.List;
import io.vavr.control.Option;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class AskQuestionConsumesQuestionTest implements UpdateLegacyGame {
    private Option&amp;lt;LegacyQuestionDeck&amp;gt; maybeUpdatedLegacyQuestionDeck = Option.none();

    @Test
    void happyPath() throws Exception {
        final QuestionDeck questionDeck = new QuestionDeck(HashMap.of(Category.POP, List.of(&amp;quot;::question 0::&amp;quot;, &amp;quot;::question 1::&amp;quot;)));

        new GameEngine(this, questionDeck).askQuestionInCategory(Category.POP, new LegacyAskQuestion() {
            @Override
            public void askQuestion(String questionText) {
                // Intentionally do nothing; we&amp;#39;re checking _consuming_ a question, and not asking it.
            }
        });

        final QuestionDeck updatedQuestionDeck = new QuestionDeck(HashMap.of(Category.POP, List.of(&amp;quot;::question 1::&amp;quot;)));

        Assertions.assertEquals(
                updatedQuestionDeck,
                questionDeck
        );

        Assertions.assertEquals(
                Option.of(updatedQuestionDeck.asLegacyQuestionDeck()),
                maybeUpdatedLegacyQuestionDeck
        );
    }

    @Override
    public void updateQuestionDeckFields(LegacyQuestionDeck legacyQuestionDeck) {
        this.maybeUpdatedLegacyQuestionDeck = Option.of(legacyQuestionDeck);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;aside&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;I’ve chosen to handroll my test doubles just because I haven’t needed them much yet and I didn’t want to become distracted by &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/jmock-v-mockito-but-not-to-the-death&quot;&gt;Mockito nor JMock&lt;/a&gt; while I finish this move. I can refactor towards one of those libraries later.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this test I want to &lt;em&gt;check&lt;/em&gt; that when the new &lt;code&gt;GameEngine&lt;/code&gt; asks a question, something updates the legacy state of the question deck; however, asking a question involves writing text to the console, which I prefer to avoid in a microtest. I have introduced an interface (a Named Lambda Expression or Functional Interface) to side-step the unwanted side-effect. In this test, I don’t care about asking the question, but only about &lt;em&gt;consuming the correct question&lt;/em&gt; in order to avoid asking it twice in succession, which explains why I stub &lt;code&gt;LegacyAskQuestion&lt;/code&gt; to do nothing. This stubbing distracts me (and anyone who reads this test) from the goal of the test. I interpret that distraction as a signal that I have too many responsibilities in one place. &lt;strong&gt;I can already see myself needing to duplicate this irrelevant detail in more microtests&lt;/strong&gt;, and that typically &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;tells me to separate behaviors from each other&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;identifying-some-refactorings&quot;&gt;Identifying Some Refactorings&lt;/h2&gt;
&lt;p&gt;I can’t chase all the rabbits&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, but I &lt;em&gt;can&lt;/em&gt; write down what comes to my mind, so I add some microtask comments.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public class GameEngine {
[...]
    public void askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) {
        // SMELL I have to remember to update the legacy Game.
        // REFACTOR Move this into a Decorator on the Question Deck?
        // REFACTOR Invert askQuestion() so that we can do all of this on the Question Deck?
        final String nextQuestionInCategory = questionDeck.getNextQuestionInCategory(category);
        askQuestion.askQuestion(nextQuestionInCategory);
        questionDeck.consumeNextQuestionInCategory(category);
        updateLegacyGame.updateQuestionDeckFields(questionDeck.asLegacyQuestionDeck());
    }
[...]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;grouping-behavior-by-intention&quot;&gt;Grouping Behavior By Intention&lt;/h2&gt;
&lt;p&gt;Next, I use the &lt;a href=&quot;https://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html&quot;&gt;Composed Method pattern&lt;/a&gt; to summarize the code and express its intent more directly.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;[...]
public class GameEngine {
[...]
    public void askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) {
        // SMELL I have to remember to update the legacy Game.
        // REFACTOR Move this into a Decorator on the Question Deck?
        // REFACTOR Invert askQuestion() so that we can do all of this on the Question Deck?
        askQuestionInCategoryWith(category, askQuestion);
        signalLegacyStateChanged();
    }

    private void signalLegacyStateChanged() {
        updateLegacyGame.updateQuestionDeckFields(questionDeck.asLegacyQuestionDeck());
    }

    private void askQuestionInCategoryWith(Category category, LegacyAskQuestion askQuestion) {
        final String nextQuestionInCategory = questionDeck.getNextQuestionInCategory(category);
        askQuestion.askQuestion(nextQuestionInCategory);
        questionDeck.consumeNextQuestionInCategory(category);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might not consider this a substantial improvement, but summarizing the behavior of “ask the next question in this category” clearly isolates the &lt;em&gt;new code&lt;/em&gt; (asking-then-consuming a question) from the &lt;em&gt;legacy code&lt;/em&gt; (updating the legacy state). But wait! Something wonderful has happened.&lt;/p&gt;
&lt;h1 id=&quot;the-moment&quot;&gt;The Moment&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest&quot;&gt;In extracting methods, I have been forced to name them&lt;/a&gt;, and in naming them, I notice a pattern that I’ve seen numerous times over the years: two methods that do similar things, have similar names, but whose names differ in some vague way. Here, those two methods are “ask question in category” and “ask question in category &lt;em&gt;with&lt;/em&gt;”.&lt;/p&gt;
&lt;p&gt;“With”?! Strange name. It doesn’t seem to mean anything here.&lt;/p&gt;
&lt;p&gt;Even better, the two methods have the &lt;em&gt;same&lt;/em&gt; parameter list: a category and a Named Lambda Expression for actually asking the question. The word “actually” in that sentence acts like a clue.&lt;/p&gt;
&lt;p&gt;Even betterer, one method calls the other &lt;em&gt;and&lt;/em&gt; does a dash extra.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;Is your intuition tingling yet?&lt;/a&gt; Don’t worry if it isn’t, but I thought I’d ask.&lt;/p&gt;
&lt;h2 id=&quot;the-symptoms&quot;&gt;The Symptoms&lt;/h2&gt;
&lt;p&gt;I have duplication between methods with similar names. I &lt;em&gt;want&lt;/em&gt; to name them identically, since they both involve asking the next question in a category, but the language doesn’t let me. Like any impatient programmer, I follow a path of little resistance, adding some vague word (“with”) to the name in order to artificially distinguish the two implementations and get on with my task. (Clue!)&lt;/p&gt;
&lt;p&gt;One method invokes the other and does some extra stuff. This reminds me of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Decorator_pattern&quot;&gt;Decorator pattern&lt;/a&gt;. (Clue!)&lt;/p&gt;
&lt;h2 id=&quot;the-realization&quot;&gt;The Realization&lt;/h2&gt;
&lt;figure class=&quot;half-width&quot;&gt;
&lt;img src=&quot;/images/Emerging-Implementations-of-an-Emerging-Interface-An-Example/decorator-diagram.png&quot; /&gt;
&lt;figcaption&gt;
The typical Decorator design
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Decorator pattern, like the &lt;a href=&quot;https://en.wikipedia.org/wiki/Composite_pattern&quot;&gt;Composite pattern&lt;/a&gt;, involves multiple implementations of a common interface where one implementation adds behavior to—&lt;em&gt;decorates&lt;/em&gt;—another. If I want the Decorator pattern here, then surely I must have multiple implementations of a common interface! And clearly I do.&lt;/p&gt;
&lt;p&gt;The artificial, vague difference in name between “ask question in category” and “ask question in category with” signals two implementations of “ask question in category” (a “standard” one and a “special” one), while the same method signature (&lt;code&gt;(Category, LegacyAskQuestion) -&amp;gt; void&lt;/code&gt;) signals the common interface.&lt;/p&gt;
&lt;h1 id=&quot;the-refactoring-a-summary&quot;&gt;The Refactoring: A Summary&lt;/h1&gt;
&lt;p&gt;I approach this situation with the following strategy.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Rename the methods to reveal the implementation details that distinguish them from each other.&lt;/li&gt;
&lt;li&gt;Move the implementation details onto new classes.&lt;/li&gt;
&lt;li&gt;Extract the common interface.&lt;/li&gt;
&lt;li&gt;Profit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Great, no? You can practise these steps on your own or you can read on to see a summary of how I did it. For the gory details and the wonderful design insights that followed, &lt;a href=&quot;https://surviving-legacy-code.jbrains.ca&quot;&gt;you’ll need to purchase a training course&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;rename-the-implementation-methods&quot;&gt;Rename the Implementation Methods&lt;/h2&gt;
&lt;p&gt;I start with three methods, two of which have very similar intent and very similar names.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;[...]
public class GameEngine {
[...]
    public void askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) {
        askQuestionInCategoryWith(category, askQuestion);
        signalLegacyStateChanged();
    }

    private void signalLegacyStateChanged() { [...] }
    private void askQuestionInCategoryWith(Category category, LegacyAskQuestion askQuestion) { [...] }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I look at these, &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;I have the impulse to rename the first one to “ask question in category then signal legacy state changed”&lt;/a&gt; and the last to “ask question in category”. These names, &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;though purely mechanical&lt;/a&gt;, provide an adequate &lt;em&gt;distinction&lt;/em&gt; between the two implementations through &lt;em&gt;accurate&lt;/em&gt; names in both cases and &lt;em&gt;precise&lt;/em&gt; names in the case of the “legacy state change” version. The code moves to the right on the &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;Improving Names continuum&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;[...]
public class GameEngine {
[...]
    public void askQuestionInCategoryThenUpdateLegacyState(Category category, LegacyAskQuestion askQuestion) {
        askQuestionInCategory(category, askQuestion);
        signalLegacyStateChanged();
    }

    private void signalLegacyStateChanged() { [...] }
    private void askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) { [...] }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;extract-the-implementations-and-the-common-interface&quot;&gt;Extract the Implementations and the Common Interface&lt;/h2&gt;
&lt;p&gt;This pattern in the names suggests a kind of &lt;em&gt;standard&lt;/em&gt; implementation (unmarked) and a &lt;em&gt;special&lt;/em&gt; implementation (marked by the phrase “then update legacy state”). I turn this into the Decorator pattern with the following steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Extract a class for each implementation. Copy the difference in names into the class names.&lt;/li&gt;
&lt;li&gt;Rename the methods in both classes to match each other.&lt;/li&gt;
&lt;li&gt;Extract a common interface from the two implementations.&lt;/li&gt;
&lt;li&gt;Weaken dependencies by using the Weakest Type Possible.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;trouble-in-the-tests&quot;&gt;Trouble In the Tests&lt;/h3&gt;
&lt;p&gt;In my tests, I’d like to check the standard implementation (ask question, then consume it) separately from the special implementation (do the standard thing, then update the legacy state), and yet the current design forces me to check these things together: it holds the standard implementation hostage in a &lt;code&gt;private&lt;/code&gt; method and it provides no convenient interface to allow for setting an expectation on &lt;code&gt;askQuestionInCategory()&lt;/code&gt;. The refactoring I’m doing here helps with both of these issues. Once again, &lt;a href=&quot;/permalink/becoming-an-accomplished-software-designer&quot;&gt;my intuition (how do I make this more-easily tested?) matches the mechanics (how do I remove this duplication?)&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;before&quot;&gt;Before&lt;/h2&gt;
&lt;p&gt;Before refactoring, the Decorator was flattened inside &lt;code&gt;GameEngine&lt;/code&gt;. I could only run the standard implementation through the special implementation. I could only run the special implementation by also running the standard implementation. This led to integrated tests which would have caused irrelevant details to proliferate if I hadn’t noticed the risk early on. And yet, the code is so small, that all those risks can seem easy to handle. To that I say this: &lt;strong&gt;if the risks are easy to handle now, then they’re also easy to address now.&lt;/strong&gt; (Sometimes it’s better to do nothing. Good judgment comes from experience, which comes from bad judgment.)&lt;/p&gt;
&lt;h2 id=&quot;after&quot;&gt;After&lt;/h2&gt;
&lt;p&gt;After extracting the Decorator, we have the following.&lt;/p&gt;
&lt;p&gt;The legacy &lt;code&gt;Game&lt;/code&gt; delegates &lt;code&gt;askQuestion()&lt;/code&gt; to the &lt;code&gt;GameEngine&lt;/code&gt;, hiding from it the details of how to ask a question in production (by writing text to the console). The &lt;code&gt;Game&lt;/code&gt; uses the &lt;a href=&quot;https://wiki.c2.com/?SelfShuntPattern&quot;&gt;Self-Shunt Pattern&lt;/a&gt; to update its legacy state when asked to.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package com.adaptionsoft.games.uglytrivia;
[...]
public class Game implements UpdateLegacyGame {
[...]
    private final GameEngine gameEngine;

    /*
     * BEGIN Legacy fields. Maintain backwards compatibility
     * at all costs until 2021-06-30.
     */
[...]
    LinkedList popQuestions = new LinkedList();
    LinkedList scienceQuestions = new LinkedList();
    LinkedList sportsQuestions = new LinkedList();
    LinkedList rockQuestions = new LinkedList();
[...]
    // Creating the standard question decks lives elsewhere, but
    // starting the Game triggers &amp;quot;update question decks in legacy game&amp;quot;.
    public  Game(){
        this.gameConfiguration = GameConfiguration.withStandardQuestionDecks(this);
        this.gameEngine = gameConfiguration.start();
    }
[...]
    // We&amp;#39;re using Java 6, so Functional Interface in place of lambda expression.
    private void askQuestion() {
        gameEngine.askQuestionInCategoryThenUpdateLegacyState(
                findCategoryByLegacyName(currentCategory()),
                new LegacyAskQuestion() {
                    @Override
                    public void askQuestion(String questionText) {
                        System.out.println(questionText);
                    }
                });
    }
[...]
    private void updateQuestionDeck(final LinkedList oldQuestionDeck, final java.util.List&amp;lt;?&amp;gt; newQuestionDeckContents) {
        oldQuestionDeck.clear();
        oldQuestionDeck.addAll(newQuestionDeckContents);
    }

    @Override
    public void updateQuestionDeckFields(LegacyQuestionDeck legacyQuestionDeck) {
        updateQuestionDeck(this.popQuestions, legacyQuestionDeck.getPopQuestions());
        updateQuestionDeck(this.scienceQuestions, legacyQuestionDeck.getScienceQuestions());
        updateQuestionDeck(this.sportsQuestions, legacyQuestionDeck.getSportsQuestions());
        updateQuestionDeck(this.rockQuestions, legacyQuestionDeck.getRockQuestions());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The legacy behavior remains here. The legacy &lt;code&gt;Game&lt;/code&gt; only injects into the Happy Zone an implementation of the action “update the legacy state”.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;GameEngine&lt;/code&gt; provides a simple Facade into the Happy Zone. I don’t need this Facade yet, so I could invoke YAGNI, but as soon as I want to move behavior from the legacy code into the Happy Zone, I’ll prefer having this Facade. When I first started refactoring, I’d have removed this Facade, then put it back when I truly needed it, but in the intervening 20 years, I’ve grown to trust myself when I say that I will need it very soon. I treat YAGNI as a principle, and not a rule. (Maybe you need to treat it as a rule.)&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia;

import ca.jbrains.trivia.legacy.LegacyAskQuestion;

public class GameEngine {
    private final LegacyStateUpdatingAskQuestionInCategory legacyStateUpdatingAskQuestionInCategory;

    public GameEngine(final LegacyStateUpdatingAskQuestionInCategory legacyStateUpdatingAskQuestionInCategory) {
        this.legacyStateUpdatingAskQuestionInCategory = legacyStateUpdatingAskQuestionInCategory;
    }

    public void askQuestionInCategoryThenUpdateLegacyState(Category category, LegacyAskQuestion askQuestion) {
        legacyStateUpdatingAskQuestionInCategory.askQuestionInCategory(category, askQuestion);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I left the legacy state details in this class to clarify its intent: it sits in the DMZ, which protects the Happy Zone from the Horrible Outside/Legacy World. It might talk to the legacy code directly, but certainly, at worst, it provides the anti-corruption layer that shields the Happy Zone from the details of the legacy code. I will continue to look for ways to invert the dependency so the legacy code knows about this class, but this class remains ignorant of the legacy code.&lt;/p&gt;
&lt;h3 id=&quot;the-decorator&quot;&gt;The Decorator&lt;/h3&gt;
&lt;p&gt;First, the common interface.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia;

import ca.jbrains.trivia.legacy.LegacyAskQuestion;

public interface AskQuestionInCategory {
    QuestionDeck askQuestionInCategory(Category category, LegacyAskQuestion askQuestion);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, the standard implementation.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia;

import ca.jbrains.trivia.legacy.LegacyAskQuestion;

/*
 * REFACTOR Move the LegacyAskQuestion parameter into the constructor.
 * REFACTOR Move the QuestionDeck parameter into askQuestionInCategory().
 */
public class StandardAskQuestionInCategory implements AskQuestionInCategory {
    private final QuestionDeck questionDeck;

    public StandardAskQuestionInCategory(QuestionDeck questionDeck) {
        this.questionDeck = questionDeck;
    }

    @Override
    public QuestionDeck askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) {
        final String nextQuestionInCategory = questionDeck.getNextQuestionInCategory(category);
        askQuestion.askQuestion(nextQuestionInCategory);
        questionDeck.consumeNextQuestionInCategory(category);
        return questionDeck;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can’t think of a better name than “standard”, so I leave it like this for now. This is the part that “actually” asks a question. At some point, I’ll find better names. Other programmers might name this class &lt;code&gt;AskQuestionInCategoryImpl&lt;/code&gt;, to mean “the standard way we do it around here”. I find the word “standard” more honest, more direct, and easier to justify than “impl”, let alone the abbreviation.&lt;/p&gt;
&lt;p&gt;Next, the “special” implementation. What makes this special? It updates the legacy state when it knows that the question deck has changed.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; This helps me name the class more explicitly and more precisely.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia;

import ca.jbrains.trivia.legacy.LegacyAskQuestion;
import ca.jbrains.trivia.legacy.UpdateLegacyGame;

public class LegacyStateUpdatingAskQuestionInCategory implements AskQuestionInCategory {
    private final UpdateLegacyGame updateLegacyGame;
    private final AskQuestionInCategory askQuestionInCategory;

    public LegacyStateUpdatingAskQuestionInCategory(UpdateLegacyGame updateLegacyGame, AskQuestionInCategory askQuestionInCategory) {
        this.updateLegacyGame = updateLegacyGame;
        this.askQuestionInCategory = askQuestionInCategory;
    }

    public QuestionDeck askQuestionInCategory(Category category, LegacyAskQuestion askQuestion) {
        final QuestionDeck questionDeck = askQuestionInCategory.askQuestionInCategory(category, askQuestion);
        updateLegacyGame.updateQuestionDeckFields(questionDeck.asLegacyQuestionDeck());
        return questionDeck;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Decorator part comes from this implementation decorating an arbitrary implementation of the common interface, then delegating to that object. This feels a bit like Aspect-Oriented Programming: after “ask question in category”, update the legacy question deck fields. Any client that knows how to talk to a generic “ask question in category” action can easily add the “update legacy state” behavior with a change of a single line of code.&lt;/p&gt;
&lt;p&gt;Finally, just for completeness, here is &lt;code&gt;QuestionDeck&lt;/code&gt;, which can turn itself into a data structure that facilitates updating the legacy state. I don’t like this logical dependency back on the Horrible Legacy World, but at least it only depends on Value Objects arranged in a certain shape, rather than classes that &lt;em&gt;must&lt;/em&gt; run in the legacy environment. I can live with that for now. I can’t chase all the rabbits! As it is, this class needs to know about the &lt;em&gt;four production question categories&lt;/em&gt;, anyway, so at least the presence of more of these details makes that logical dependency easier to spot. I’m more likely to try to fix it if I keep noticing it.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.trivia;

import ca.jbrains.trivia.legacy.LegacyQuestionDeck;
import io.vavr.collection.HashMap;
import io.vavr.collection.List;

import java.util.ArrayList;
import java.util.function.Supplier;

public final class QuestionDeck {
    private HashMap&amp;lt;Category, List&amp;lt;String&amp;gt;&amp;gt; questionsByCategory;

    public QuestionDeck(HashMap&amp;lt;Category, List&amp;lt;String&amp;gt;&amp;gt; questionsByCategory) {
        this.questionsByCategory = questionsByCategory;
    }

    public static Supplier&amp;lt;RuntimeException&amp;gt; noQuestionsInCategoryProgrammerMistake(Category category) {
        return () -&amp;gt; new IllegalStateException(String.format(&amp;quot;How are there no questions in the category named &amp;#39;%s&amp;#39;?!&amp;quot;, category.name()));
    }

    /*
     * CONTRACT For convenience, use an empty list of questions as the fallback value
     * when this object has no questions in one of the expected legacy categories.
     */
    public LegacyQuestionDeck asLegacyQuestionDeck() {
        return new LegacyQuestionDeck(
                asLegacyQuestionsInCategory(Category.POP),
                asLegacyQuestionsInCategory(Category.SCIENCE),
                asLegacyQuestionsInCategory(Category.SPORTS),
                asLegacyQuestionsInCategory(Category.ROCK));
    }

    private java.util.List&amp;lt;String&amp;gt; asLegacyQuestionsInCategory(Category category) {
        return questionsByCategory.get(category).getOrElse(List.empty()).toJavaList();
    }

    public String getNextQuestionInCategory(Category category) {
        return getQuestionsInCategory(category).head();
    }

    public void consumeNextQuestionInCategory(Category category) {
        questionsByCategory = questionsByCategory.put(category, getRemainingQuestionsInCategory(category));
    }

    private List&amp;lt;String&amp;gt; getRemainingQuestionsInCategory(Category category) {
        return getQuestionsInCategory(category).tail();
    }

    /*
     * CONTRACT For now, we must support the four expected legacy Game categories.
     * We want to remove this restriction.
     */
    public List&amp;lt;String&amp;gt; getQuestionsInCategory(Category category) {
        return questionsByCategory.get(category).getOrElseThrow(noQuestionsInCategoryProgrammerMistake(category));
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof QuestionDeck) {
            QuestionDeck that = (QuestionDeck) other;
            return this.questionsByCategory.equals(that.questionsByCategory);
        }
        else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return -762;
    }

    @Override
    public String toString() {
        return String.format(&amp;quot;QuestionDeck[questionsByCategory=[%s]]&amp;quot;, questionsByCategory);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you wanted to see the gory details, you’d need to purchase &lt;a href=&quot;https://surviving-legacy-code&quot;&gt;Surviving Legacy Code&lt;/a&gt;, where I’ve published them in article form, to be followed in summer 2019 with a video showing all the steps. This course not only shows you step-by-step how to refactor like this, but it’s like pairing with me: I tell you what I’m thinking as I think it, including how I deal with distractions, how I recover from going in the wrong direction for a while, and all the other aspects of real-life evolutionary design.&lt;/p&gt;
&lt;h3 id=&quot;wont-somebody-think-of-the-tests&quot;&gt;Won’t Somebody Think of the Tests?!&lt;/h3&gt;
&lt;p&gt;Yes, of course! A test changed. Usually this kind of refactoring makes an integrated test more obvious to the reader as an integrated test. Did it? Let’s look.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;[...]
public class AskQuestionConsumesQuestionTest implements UpdateLegacyGame {
    private Option&amp;lt;LegacyQuestionDeck&amp;gt; maybeUpdatedLegacyQuestionDeck = Option.none();

    @Test
    void happyPath() throws Exception {
        final QuestionDeck questionDeck = new QuestionDeck(HashMap.of(Category.POP, List.of(&amp;quot;::question 0::&amp;quot;, &amp;quot;::question 1::&amp;quot;)));

        final GameEngine gameEngine = new GameEngine(
                new LegacyStateUpdatingAskQuestionInCategory(
                        this,
                        questionDeck,
                        new StandardAskQuestionInCategory(questionDeck)));

        gameEngine.askQuestionInCategoryThenUpdateLegacyState(Category.POP, new LegacyAskQuestion() {
            @Override
            public void askQuestion(String questionText) {
                // Intentionally do nothing; we&amp;#39;re checking _consuming_ a question, and not asking it.
            }
        });

        final QuestionDeck updatedQuestionDeck = new QuestionDeck(HashMap.of(Category.POP, List.of(&amp;quot;::question 1::&amp;quot;)));

        Assertions.assertEquals(
                updatedQuestionDeck,
                questionDeck
        );

        Assertions.assertEquals(
                Option.of(updatedQuestionDeck.asLegacyQuestionDeck()),
                maybeUpdatedLegacyQuestionDeck
        );
    }

    @Override
    public void updateQuestionDeckFields(LegacyQuestionDeck legacyQuestionDeck) {
        this.maybeUpdatedLegacyQuestionDeck = Option.of(legacyQuestionDeck);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why yes! This test involves &lt;code&gt;StandardAskQuestionInCategory&lt;/code&gt; (which will try to ask the question using &lt;code&gt;LegacyAskQuestion&lt;/code&gt;) even though it also explicitly passes a &lt;code&gt;LegacyAskQuestion&lt;/code&gt; implementation that won’t even try to ask the question! I see this pattern a lot: I have to stub something &lt;em&gt;way over there&lt;/em&gt; in order to control the behavior of something &lt;em&gt;right here&lt;/em&gt;. This tells me that I’m missing an abstraction, and it gives me some ideas of where else to refactor. I could simplify the test by replacing the standard implementation of &lt;code&gt;AskQuestionInCategory&lt;/code&gt; with a stub that does nothing.&lt;/p&gt;
&lt;p&gt;But then I would have have &lt;em&gt;two&lt;/em&gt; stubs that do nothing. They do &lt;em&gt;the same kind of nothing&lt;/em&gt;. And &lt;em&gt;for the same reasons&lt;/em&gt;. More ideas! Removing that duplication would take more than two minutes, so I add a SMELL comment, put a task in the inbox, and finish this move.&lt;/p&gt;
&lt;p&gt;I have the feeling that these symptoms all point to the same underlying cause. It feels like a dependency in the wrong direction. I suspect that inverting that dependency, moving the “update legacy state” behavior down into &lt;code&gt;QuestionDeck&lt;/code&gt;, would simplify this design &lt;em&gt;significantly&lt;/em&gt;. It feels like I’d benefit from making that move soon.&lt;/p&gt;
&lt;p&gt;Wait… &lt;strong&gt;I think I finally finished this move!&lt;/strong&gt; Let me look around the code…. Yes, I did it!&lt;/p&gt;
&lt;p&gt;Breathe. Where do I go from here? What do I see now that I can pull my head up out of the details?&lt;/p&gt;
&lt;h2 id=&quot;the-state-of-the-inbox&quot;&gt;The State of the Inbox&lt;/h2&gt;
&lt;p&gt;One item in the inbox has become urgent and the rest I’ve left as an unprocessed set of tasks for now.&lt;/p&gt;
&lt;h3 id=&quot;urgent&quot;&gt;Urgent&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LegacyStateUpdatingAskQuestionInCategory&lt;/code&gt; knows too many details about its collaborators, resulting in Programming by Coincidence.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;unprocessed&quot;&gt;Unprocessed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Add microtests for the implementations of &lt;code&gt;AskQuestionInCategory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Resolve the collision of names and concepts between &lt;code&gt;AskQuestionInCategory&lt;/code&gt; and &lt;code&gt;LegacyAskQuestion&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Maybe move the Decorator design down into &lt;code&gt;QuestionDeck&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Move &lt;code&gt;LegacyAskQuestion&lt;/code&gt; into the constructor of the implementations of &lt;code&gt;AskQuestionInCategory&lt;/code&gt; that need them.&lt;/li&gt;
&lt;li&gt;Remove the excess details in &lt;code&gt;AskQuestionConsumesQuestionTest&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;…and then, &lt;code&gt;AskQuestionConsumesQuestionTest&lt;/code&gt; duplicates “do nothing” stubs for both &lt;code&gt;AskQuestionInCategory&lt;/code&gt; and &lt;code&gt;LegacyAskQuestion&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I already see a way to remove that Programming by Coincidence risk, but that’s not the point of this article. Maybe you’ve already noticed it? Maybe you’ll run into the same thing if you &lt;a href=&quot;https://www.github.com/jbrains/trivia&quot;&gt;try to refactor the code yourself&lt;/a&gt;. Maybe you’d rather just &lt;a href=&quot;https://surviving-legacy-code.jbrains.ca&quot;&gt;find out what I’m talking about&lt;/a&gt;. (Sorry: that service is not free.)&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;Here I’ve tried to show an example of replacing two similar-but-vaguely-different methods with the Decorator pattern, which makes the code less expensive to test. This refactoring results in smaller pieces that I could more-easily recombine, giving me more options and reducing the cost of changing &lt;em&gt;peripheral behavior&lt;/em&gt; (like how to update legacy state, or even whether we still need to do it) from &lt;em&gt;essential behavior&lt;/em&gt; (ask a question, then move it to the back of the deck so as not to ask it again right away). It nudges the code towards the Open/Closed Principle by treating “ask a question” as an abstraction, rather than relying on the current production implementation, which will continue to change as we rescue more code from the legacy &lt;code&gt;Game&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can see a similar example &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/beyond-mock-objects&quot;&gt;here&lt;/a&gt;, where I extract a Decorator that adds the current timestamp to all incoming requests that need it, so that I can test handling a request without worrying about where the timestamp came from. The &lt;code&gt;InstantaneousRequestController&lt;/code&gt; decorates other Controllers in exactly the same way as Rails uses request filters.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names&quot;&gt;“A Model for Improving Names”&lt;/a&gt;. I don’t worry about naming things for their structure, but I continually look for opportunities to rename those things in a way that increases abstraction.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;“Becoming An Accomplished Software Designer”&lt;/a&gt;. An essay on the interplay between mechanical refactoring and design intuition.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.thecodewhisperer.com/permalink/beyond-mock-objects&quot;&gt;“Beyond Mock Objects”&lt;/a&gt;. I happily use test doubles (mock objects) as a design tool, but sometimes my design improves by figuring out how to avoid a test double.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Have you ever tried chasing dozens of rabbits at once? They have evolved to run away from you. I know that you want to hug all the rabbits, but you’ll fail until you pick one and chase &lt;em&gt;it&lt;/em&gt; until you catch it and hug it.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Eclipse calls this “Generalize Declared Type”. IntelliJ IDEA calls this “Use Interface Where Possible”. Replace the declared type of a field (or variable or parameter) with the highest possible type on the inheritance hierarchy, meaning the most-abstract type, that the compile-time type checker will allow. This applies the &lt;a href=&quot;/series#dependency-inversion-principle-dip&quot;&gt;Dependency Inversion Principle&lt;/a&gt; and/or the Interface Segregation Principle.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Yes, I see a clue in that sentence, too. I probably want to move the “update legacy state” event down into &lt;code&gt;QuestionDeck&lt;/code&gt; itself, so that the &lt;code&gt;Game&lt;/code&gt; can simply subscribe to it for state changes. If you want to try that, then you should! I will probably get the eventually. I feel no rush. In fact, &lt;a href=&quot;https://surviving-legacy-code.jbrains.ca&quot;&gt;that will probably make for an interesting refactoring exercise in the course&lt;/a&gt;.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 20 Jun 2019 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/Emerging-Implementations-of-an-Emerging-Interface-An-Example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/Emerging-Implementations-of-an-Emerging-Interface-An-Example</guid>
        
        
        <category>Simple Design</category>
        
        <category>Evolutionary Design</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>A Contract Is Just An Understanding</title>
        <description>&lt;p&gt;A recent tweet caught my attention.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
The drawback of ‘contract’ as a metaphor is that it leads to discussion as to whether a party is right (conforms) or wrong (violates) instead of overall outcome (what’s the best way to make the system meet the needs of the stakeholders in our technical/economic context).
&lt;/p&gt;
— Nat Pryce (&lt;span class=&quot;citation&quot; data-cites=&quot;natpryce&quot;&gt;@natpryce&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/natpryce/status/1133277617686233094?ref_src=twsrc%5Etfw&quot;&gt;May 28, 2019&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;When I read this, one thought immediately came to my mind: &lt;strong&gt;are people &lt;em&gt;really&lt;/em&gt; doing this?!&lt;/strong&gt; And &lt;em&gt;of course&lt;/em&gt; they are, because people relentlessly find ways to interpret what they see and hear in their favor. I don’t cite this as a problem to fix, but rather a tendency not to ignore.&lt;/p&gt;
&lt;p&gt;A Client might want to focus on conformance so that they could blame the Supplier in case the software didn’t behave as expected. A clear contract would help the Client direct their blame precisely and, I expect, more forcefully. A Supplier might want to focus on conformance so that they could deflect blame when a Client made an honest mistake regarding what to expect from the Supplier’s software component. And so it goes. I understand.&lt;/p&gt;
&lt;p&gt;Very well… since I have spent the last 15 years or so talking about &lt;em&gt;contract tests&lt;/em&gt; as a way to avoid the &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests scam&lt;/a&gt;, I feel duty-bound to say this clearly to anyone who might ever be listening: &lt;strong&gt;a software contract merely documents an understanding of what each part of the system can expect from the others&lt;/strong&gt;. An &lt;strong&gt;understanding&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Merely an understanding—and one that remains subject to change.&lt;/p&gt;
&lt;h2 id=&quot;how-i-use-contracts&quot;&gt;How I Use Contracts&lt;/h2&gt;
&lt;p&gt;As a Client, I like clear, well-documented contracts so that I can figure out which behavior I can safely rely on and which I should not. A “good” contract helps me understand where the system’s design is more stable and where it is more likely to change. This also subtly nudges me in the direction of designing components to become more stable (OCP). Clear contracts also alert me to situations where I’ve started relying too much on too many details of my suppliers (ISP) and a previously-unneeded abstraction would now help. In that situation, I could introduce the abstraction myself, then try to donate that part of the system to the Suppliers (internal open-source model). This would give them the option to offer a &lt;a href=&quot;https://raganwald.com/2013/10/08/defactoring.html&quot;&gt;defactored&lt;/a&gt; design to Clients who prefer ease of use over flexibllity, while retaining the factored, toolkit-like design for Clients who need flexibility at the cost of some up-front cost in understanding (make routine things easy, and unusual things possible). I want contracts that help me understand the likely future cost of depending directly on another part of the system.&lt;/p&gt;
&lt;p&gt;As a Supplier, I want to offer clear, well-documented contracts for all those same reasons, but also in order to negotiate openly about the boundaries between what I will do and what my Clients will need to do. I see so many groups struggle with unclear boundaries due to an unwillingness to negotiate this openly (and in more-serious contexts than software component behavior!). I understand their reticence, but when we clearly delineate what my stuff does from what your stuff needs to do, everyone finishes their work sooner.&lt;/p&gt;
&lt;p&gt;I often act as both Client and Supplier here, and in those situations, I mostly use contracts to document my understanding so that my future self doesn’t need to reverse-engineer that understanding months or years later. Documenting contracts also helps me spot unhealthy dependencies as they evolve, rather than after they become entrenched and I feel too much resistance to change them.&lt;/p&gt;
&lt;p&gt;I do not treat software contracts as permanent decisions about the behavior of software components. Instead, I treat them as documentation of the most-recent decisions and as a starting point for future negotiations. I document these decisions in contracts &lt;a href=&quot;https://blog.jbrains.ca/permalink/getting-started-with-getting-things-done&quot;&gt;so that we don’t need to carry the current state of these agreements in our heads&lt;/a&gt;. Why waste the energy? Just write it down!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I treat software contracts as a record of decisions, with the goal of offering clarity to the project community.&lt;/strong&gt; Changing those decisions might cost more than we’d like, but change remains possible, if not always welcome. “Good” software contracts help us understand and even visualize the impact of changing those decisions. We do this work more consciously and with much less unplanned work. We don’t scramble to “roll forward” once we’ve “committed” to make a certain change; instead, we go into these changes with our eyes open and we can better control the damage. We can, I dare say, &lt;em&gt;manage&lt;/em&gt; the work.&lt;/p&gt;
&lt;p&gt;Even so, I understand: people are people, and some people will focus on enforcement over understanding or on conformance over communication. I can’t stop them. I can only write articles like this and hope that someone, somewhere realizes that they don’t have to think about contracts in such a narrow, restrictive way.&lt;/p&gt;
&lt;div class=&quot;highlight&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;A software contract is merely a record of a decision of where to put the boundaries between software components. Don’t wield them as an instrument to hold beneficial changes hostage.&lt;/p&gt;
&lt;/div&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Reginald Braithwaite, &lt;a href=&quot;https://raganwald.com/2013/10/08/defactoring.html&quot;&gt;“Defactoring”&lt;/a&gt;. Wherein Reg reminds us what the verb “factor” in “refactoring” means and helps us avoid disappointing a Client who asked for a bicycle by giving them a bicycle construction kit.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;Beware the Integrated Tests Scam (was Integrated Tests Are a Scam): Series&lt;/a&gt;. A series of articles on the topic of integrated tests, why I shy away from them, and how to replace them with collaboration and contract tests.&lt;/p&gt;
</description>
        <pubDate>Fri, 14 Jun 2019 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-contract-is-just-an-understanding</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-contract-is-just-an-understanding</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
        <category>Simple Design</category>
        
        <category>Not Just Coding</category>
        
      </item>
    
      <item>
        <title>Gradle Won&apos;t Run My Spock Tests</title>
        <description>&lt;p&gt;I recently had this problem: I was writing some tests with Spock, but IntelliJ IDEA wouldn’t run them. It would run my JUnit tests (written with JUnit 4), but it wouldn’t run my Spock tests (or “specs”, if you prefer). At least this is how it seemed to me. I had made this work before, so I couldn’t understand at all why it didn’t work now. And, of course, I wanted to get this working for a training course, so I felt a certain pressure to get it to work. Nothing made sense to me.&lt;/p&gt;
&lt;h1 id=&quot;symptoms&quot;&gt;Symptoms&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;In IDEA, I tried to run all the tests from my &lt;code&gt;src/test&lt;/code&gt; source folder. Spock tests did not run.&lt;/li&gt;
&lt;li&gt;I tried to run all the tests from just the &lt;code&gt;src/test/groovy&lt;/code&gt; source folder. Spock tests did not run.&lt;/li&gt;
&lt;li&gt;I tried to run all the tests from just the &lt;code&gt;src/test/java&lt;/code&gt; source folder. JUnit 4 tests ran as expected.&lt;/li&gt;
&lt;li&gt;I tried to rebuild the project. No change.&lt;/li&gt;
&lt;li&gt;I tried &lt;strong&gt;Invalidate Caches and Restart&lt;/strong&gt;. No change.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I tried to run all these tests from Gradle, in order to isolate the problem to some IDEA configuration setting, but even with Gradle I saw the same behavior. I couldn’t run Spock tests. I looked inside &lt;code&gt;build/&lt;/code&gt; and saw that Gradle had built my Groovy source code, but still, Spock tests did not run. It look to me as though Gradle weren’t even trying. This seemed really strange to me, since I had created this Java project exactly the same way as I’d done in the past.&lt;/p&gt;
&lt;h1 id=&quot;the-mistake&quot;&gt;The Mistake&lt;/h1&gt;
&lt;p&gt;I forgot to add &lt;code&gt;extends Specification&lt;/code&gt; to my Spock test classes. Yup. Once I changed that, everything worked.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
TIL what happens when I forget to &quot;extend Specification&quot; when writing Spock specs: &lt;a href=&quot;https://twitter.com/hashtag/gradle?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#gradle&lt;/a&gt; silently doesn&apos;t run any tests. Sadly, it looks like a build task failure when it isn&apos;t. I wonder how I could get the feedback, &quot;I ran the tests, but there weren&apos;t any.&quot;
&lt;/p&gt;
— ☕ J. B. Rainsberger (&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/jbrains/status/1062660413396054017?ref_src=twsrc%5Etfw&quot;&gt;November 14, 2018&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
</description>
        <pubDate>Thu, 15 Nov 2018 01:11:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/gradle-wont-run-my-spock-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/gradle-wont-run-my-spock-tests</guid>
        
        
        <category>The Little Things</category>
        
      </item>
    
      <item>
        <title>The World&apos;s Shortest Article on (test &amp;&amp; commit) || revert</title>
        <description>&lt;p&gt;Doing &lt;code&gt;(test &amp;amp;&amp;amp; commit) || revert&lt;/code&gt; amounts to doing TDD &lt;em&gt;very carefully&lt;/em&gt;, as an &lt;a href=&quot;https://www.jamesshore.com/Blog/Etudes-for-Excellence.html&quot;&gt;&lt;em&gt;étude&lt;/em&gt;&lt;/a&gt;. If you already routinely take tiny steps, then you already &lt;em&gt;almost&lt;/em&gt; do TCR, but something significant might change if you do it &lt;em&gt;exactly&lt;/em&gt;. This remains to discover. Join me.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Kent Beck, &lt;a href=&quot;https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864&quot;&gt;“test &amp;amp;&amp;amp; commit || revert”&lt;/a&gt;. Kent describes the technique and makes it clear: he doesn’t know exactly how it affects the programmers just yet.&lt;/p&gt;
&lt;p&gt;James Shore, &lt;a href=&quot;https://www.jamesshore.com/Blog/Etudes-for-Excellence.html&quot;&gt;“Études for Excellence”&lt;/a&gt;. James and I both see the XP practices as exactly that: ways to practice. In the XP community, we used to say that XP was what you did once you mastered the (original) 12 (core) practices.&lt;/p&gt;
</description>
        <pubDate>Sun, 11 Nov 2018 05:21:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-worlds-shortest-article-on-test-and-commit-otherwise-revert</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-worlds-shortest-article-on-test-and-commit-otherwise-revert</guid>
        
        
        <category>Simple Design</category>
        
        <category>Microtechniques</category>
        
      </item>
    
      <item>
        <title>From Zero To NUnit With Visual Studio Code</title>
        <description>&lt;p&gt;I have a new Linux laptop and I wanted to run C# code. I had no idea where to start. I last wrote C# for money in 2004. It took me over an hour of hunting to figure out how to run a single test, so I decided to write a tutorial that could help someone else go from zero to NUnit with Visual Studio Code.&lt;/p&gt;
&lt;div class=&quot;aside&quot;&gt;
&lt;p&gt;Please add comments with suggestions for clearer explanations, additional useful details, or better instructions.&lt;/p&gt;
&lt;p&gt;I’m especially interested in knowing how to package these setup instructions to make them repeatable, since I don’t know enough yet about &lt;em&gt;how to do&lt;/em&gt; infrastructure as code.&lt;/p&gt;
&lt;/div&gt;
&lt;h1 id=&quot;assumptions&quot;&gt;Assumptions&lt;/h1&gt;
&lt;p&gt;For this tutorial, I assume that you know nothing about the modern .NET environment. You don’t know how to install anything, where to find it, nor how to use it. You might know the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I think I need to use Visual Studio or something like it. I’ve heard of VS Code.&lt;/li&gt;
&lt;li&gt;I know I want to write tests with NUnit.&lt;/li&gt;
&lt;li&gt;I know that I need to add assembly references to my C# project in order to use NUnit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ve never installed any of this stuff before—or, at least, you’ve never knowingly nor intentionally installed it.&lt;/p&gt;
&lt;h1 id=&quot;environment&quot;&gt;Environment&lt;/h1&gt;
&lt;p&gt;I’m running Pop!_OS on a System 76 Galago Pro laptop. You can safely think of this as Ubuntu 18.04. To my knowledge, I have nothing about .NET installed at all.&lt;/p&gt;
&lt;p&gt;I use &lt;code&gt;etckeeper&lt;/code&gt; in order to be able to roll back the contents of &lt;code&gt;/etc&lt;/code&gt; on my file system. I use &lt;code&gt;stow&lt;/code&gt; in order to be able to roll back the contents of my home directory’s dotfiles.&lt;/p&gt;
&lt;h1 id=&quot;the-goal&quot;&gt;The Goal&lt;/h1&gt;
&lt;p&gt;I have one immediate goal: I have some C# code with NUnit tests and I want to be able to run those tests. The C# code consists of two classes and has no entry point (“main”). I judge success by being able to run these tests as see the test results.&lt;/p&gt;
&lt;h1 id=&quot;instructions&quot;&gt;Instructions&lt;/h1&gt;
&lt;p&gt;I wanted to install VS Code, create a project, paste in some C# code, and then run the tests. I tried to do exactly that, it didn’t work, and I gathered enough information to figure out how to make it work. Now I have reordered those instructions to make them appear more orderly and intentional.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Install the .NET framework.&lt;/li&gt;
&lt;li&gt;Install Visual Studio Code.&lt;/li&gt;
&lt;li&gt;Create a C# project in VS Code.&lt;/li&gt;
&lt;li&gt;Add some packages to the project related to testing.&lt;/li&gt;
&lt;li&gt;Remove the entry point class that VS Code generated.&lt;/li&gt;
&lt;li&gt;Build and run the tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;details&quot;&gt;Details&lt;/h2&gt;
&lt;p&gt;First, verify that you don’t have anything installed related to .NET nor VS Code.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ dotnet
[Command not found]
$ code
[Command not found]
[Try to run &amp;quot;Code&amp;quot; from the desktop manager&amp;#39;s application launcher. Nothing.]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, install the .NET framework. Search the web for &lt;code&gt;install net core sdk ubuntu&lt;/code&gt;. Find &lt;a href=&quot;https://www.microsoft.com/net/download/linux-package-manager/ubuntu18-04/sdk-current&quot; class=&quot;uri&quot;&gt;https://www.microsoft.com/net/download/linux-package-manager/ubuntu18-04/sdk-current&lt;/a&gt;. Follow its instructions.&lt;/p&gt;
&lt;h2 id=&quot;install-.net-core-sdk-on-linux-ubuntu-18.04&quot;&gt;Install .NET Core SDK on Linux Ubuntu 18.04&lt;/h2&gt;
&lt;p&gt;First, I need to install the Microsoft key, their product repository, and required dependencies.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ sudo etckeeper unclean
[Nothing, so /etc has no uncommitted changes.]
# I just like to download things here.
$ pushd $HOME/Downloads
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
$ ls
[Yep, I see the new file.]
$ sudo dpkg -i packages-microsoft-prod.deb
$ popd
$ pushd /etc; sudo git status -s
[New files in /etc/apt that need committing.]
$ popd
$ sudo etckeeper commit &amp;quot;We can now install products from Microsoft&amp;#39;s repository&amp;quot;
# I guess I need this to use package repositories over HTTPS.
$ sudo apt-get install apt-transport-https
# Now I can safely use the Microsoft package repository.
$ sudo apt-get update&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I still don’t quite trust &lt;code&gt;etckeeper&lt;/code&gt;, so I check the state of &lt;code&gt;/etc&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ pushd /etc; sudo git status -s
[No uncommitted changes.]
$ sudo git log
[Evidence of having saved uncommitted changes, although that might have come from a previous working session. Either way, it&amp;#39;s fine.]
$ popd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I can install .NET Core SDK 2.1.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ sudo apt-get install dotnet-sdk-2.1
[Evidence of installing a bunch of stuff, almost certainly related to .NET Code SDK 2.1]
[Evidence of etckeeper committing after the installation.]
# Verify
$ dotnet
[The dotnet usage message.]&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;install-visual-studio-code&quot;&gt;Install Visual Studio Code&lt;/h2&gt;
&lt;p&gt;Since I have Microsoft’s product repository, I assume that it contains a version of Visual Studio Code.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ sudo apt-cache search code
[&amp;quot;Code Editing. Redefined.&amp;quot; That&amp;#39;s marketing!]
$ sudo apt-get install code
[Evidence of installation.]
[Evidence that etckeeper committed after the installation.]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I launch the newly-installed application named “Code”. It launches, then “helpfully” opens a web page telling me how to get started, forcing me to put focus back on the actual application that I launched.&lt;/p&gt;
&lt;h3 id=&quot;opt-out-of-telemetry-reporting&quot;&gt;Opt Out of Telemetry Reporting&lt;/h3&gt;
&lt;p&gt;So before I have the faintest idea how to use VS Code to do anything, a helpful window pops up telling me that I’m going to send “telemetry information” to Microsoft as I use VS Code. No, thanks.&lt;/p&gt;
&lt;p&gt;Now I have to learn about putting VS Code settings under version control, because I know that configuration settings in tools that I don’t know well can easily spiral out of control in minutes, and then I waste hours trying to get back on track.&lt;/p&gt;
&lt;p&gt;Thank you, Microsoft.&lt;/p&gt;
&lt;p&gt;Fortunately, this doesn’t hurt too badly. First, I go to &lt;code&gt;\$HOME/.config&lt;/code&gt; to find a new directory &lt;code&gt;Code&lt;/code&gt;. This seems to contain some combination of configuration data and temporary storage for VS Code. I want to put &lt;em&gt;some&lt;/em&gt; of this stuff in version control, but not &lt;em&gt;all&lt;/em&gt;, because programmers don’t care enough about separating configuration settings (I want in version control) from temporary storage (I definitely don’t want in version control).&lt;/p&gt;
&lt;p&gt;Since I use &lt;code&gt;stow&lt;/code&gt; for my dotfiles, and I had previously stowed my &lt;code&gt;.config&lt;/code&gt; directory, &lt;code&gt;\$HOME/.config&lt;/code&gt; really points to &lt;code&gt;\$DOTFILES/common/config/.config&lt;/code&gt;, where &lt;code&gt;DOTFILES&lt;/code&gt; is the root of a git repository and my “all my dotfiles” project. That git repository ignores &lt;code&gt;common/config/.config&lt;/code&gt; in general, because of so many high-churn files, so I have to choose carefully which files inside &lt;code&gt;.config&lt;/code&gt; I want to track in that git repository.&lt;/p&gt;
&lt;p&gt;I dig inside &lt;code&gt;\$DOTFILES/common/config/.config/Code&lt;/code&gt; and find user settings file called &lt;code&gt;User/settings.json&lt;/code&gt;. I want to keep versions of this.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $DOTFILES
$ git add --force common/config/.config/Code/User/settings.json
$ git commit -m &amp;quot;We now track changes to Microsoft Visual Studio Code user-level configuration settings.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;aside&quot;&gt;
&lt;p&gt;I learned later that &lt;code&gt;User/settings.json&lt;/code&gt; doesn’t exist until you add a user-level preference setting to override the system-level preferences. Great!&lt;/p&gt;
&lt;p&gt;In VS Code, I choose &lt;strong&gt;File &amp;gt; Preferences &amp;gt; Settings&lt;/strong&gt;. This opens an editor window on an empty JSON document describing your user-level preferences. &lt;strong&gt;I save this file before changing it.&lt;/strong&gt; This last action creates the file &lt;code&gt;User/settings.json&lt;/code&gt;, which I commit to my dotfiles repository before I start changing things and fall into a ditch somewhere.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now I can follow the instructions at &lt;a href=&quot;https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting&quot; class=&quot;uri&quot;&gt;https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting&lt;/a&gt; to disable sending telemetry information to Microsoft.&lt;/p&gt;
&lt;p&gt;First, I add the preference setting to the user-level preference settings file, then I commit the change to my dotfiles repository, and then I restart VS Code.&lt;/p&gt;
&lt;p&gt;I verify this step by noting that VS Code no longer pops up a warning about sending telemetry information and I simply hope that Microsoft doesn’t lie to me. It’ll be fine.&lt;/p&gt;
&lt;h3 id=&quot;install-vs-code-extensions&quot;&gt;Install VS Code Extensions&lt;/h3&gt;
&lt;p&gt;Now I install the extensions I’ll use in VS Code related to C# and NUnit.&lt;/p&gt;
&lt;p&gt;I visit &lt;a href=&quot;https://code.visualstudio.com/Docs/languages/csharp&quot; class=&quot;uri&quot;&gt;https://code.visualstudio.com/Docs/languages/csharp&lt;/a&gt; and that leads me to &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp&quot; class=&quot;uri&quot;&gt;https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp&lt;/a&gt;. Inside VS Code, I execute &lt;code&gt;ext install ms-vscode.csharp&lt;/code&gt; using the &lt;strong&gt;Quick Open&lt;/strong&gt; command.&lt;/p&gt;
&lt;pre class=&quot;vscode&quot;&gt;&lt;code&gt;# Inside VS Code
Press Ctrl+P to launch VS Code Quick Open
Paste &amp;quot;ext install ms-vscode.csharp&amp;quot; into the little dialog.
[A window pops up to show evidence that there is now a C# extension installed.]&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;create-the-vs-code-project&quot;&gt;Create The VS Code Project&lt;/h2&gt;
&lt;p&gt;Since tools like VS Code always have magical wizards to create new projects and since I don’t know much about the contents of a C# project, I ask VS Code to create a new project, so that I can delete most of it and replace it with the code I want to run.&lt;/p&gt;
&lt;p&gt;And… of &lt;em&gt;course&lt;/em&gt;, VS Code doesn’t have a menu item for “new project”, so I hunt down how to do that. Happily, the .NET SDK makes that relatively painless and I &lt;em&gt;like&lt;/em&gt; doing this from the transparency of the command line.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $WORKSPACES_ROOT  # The path where I like to put all my projects.
$ dotnet new console -o $PROJECT_NAME  # PROJECT_NAME is a directory name
[Evidence of creating a project.]
# Verify
$ find $PROJECT_NAME
[Program.cs and some object files and a project file of type .csproj.]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I put these assets into version control, but again, I don’t know what I’m doing, so I rely on &lt;a href=&quot;https://www.toptal.com/developers/gitignore/&quot;&gt;gitignore.io&lt;/a&gt; to generate &lt;code&gt;.gitignore&lt;/code&gt; for me.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_NAME
$ git init
$ curl -L -o .gitignore https://www.gitignore.io/api/csharp,vscode
$ cat .gitignore
[It seems to have a lot of useful things in it.]
$ git add --dry-run --all
[This only adds .gitignore, Program.cs, and the project file, which seems perfectly reasonable so far.]
$ git add --all
$ git commit --message &amp;quot;We now have the default .NET C# project.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I open this project in VS Code by opening Explorer (&lt;strong&gt;View &amp;gt; Explorer&lt;/strong&gt;), pressing &lt;strong&gt;Open Folder&lt;/strong&gt;, then choosing &lt;code&gt;\$PROJECT_NAME&lt;/code&gt;, meaning the root of the project that I created with &lt;code&gt;dotnet new&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Right away, VS Code tries to build the project, and it pops up a window telling me that the project needs some more assets to build the project, so I agree to add those assets by pressing &lt;strong&gt;Yes&lt;/strong&gt;. Since that adds things that &lt;code&gt;.gitignore&lt;/code&gt; appears not to ignore, I look at them to decide for myself whether I want to track them in version control.&lt;/p&gt;
&lt;p&gt;The file &lt;code&gt;.vscode/launch.json&lt;/code&gt; appears to have launch commands and that seems handy to track. The file &lt;code&gt;.vscode/tasks.json&lt;/code&gt; appears to have a build command and that seems handy to track. I decide to track them both.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ git add --all
$ git commit --message &amp;quot;We can now build the project in VS Code.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;build-and-run-the-project-without-vs-code&quot;&gt;Build And Run The Project Without VS Code&lt;/h2&gt;
&lt;p&gt;Since .NET SDK offers these nice commands, I want to learn to use them.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT   # Currently $WORKSPACE_ROOT/$PROJECT_NAME
$ dotnet build
[Evidence of building. No warnings, no errors.]
$ dotnet run
Hello World!
# Program.cs indeed asks to print this message to the console, so everything seems to work.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;build-and-run-the-project-with-vs-code&quot;&gt;Build And Run The Project With VS Code&lt;/h2&gt;
&lt;p&gt;I go back inside VS Code and choose &lt;strong&gt;Tasks &amp;gt; Run Build Task&lt;/strong&gt;, then enter &lt;strong&gt;build&lt;/strong&gt; for the name of the task. VS Code shows evidence of building the project. This task seems to correspond with the entry in &lt;code&gt;.vscode/tasks.json&lt;/code&gt;, so I learn something there.&lt;/p&gt;
&lt;p&gt;Next, I choose &lt;strong&gt;Debug &amp;gt; Start Without Debugging&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;aside&quot;&gt;
&lt;p&gt;The UX specialists at Microsoft decided that &lt;strong&gt;Run&lt;/strong&gt; would confuse programmers, so instead they chose to name the menu item &lt;strong&gt;Start Without Debugging&lt;/strong&gt; and put it under the menu item &lt;strong&gt;Debug&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This tells me a lot about what the average .NET programmer expects. &lt;em&gt;Not&lt;/em&gt; debugging becomes the exception, rather than the rule.&lt;/p&gt;
&lt;p&gt;This also reminds me of &lt;code&gt;sudo add-apt-repository --remove {repository_name}&lt;/code&gt;. Srsly.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I see &lt;code&gt;Hello World!&lt;/code&gt; in the &lt;strong&gt;Debug Console&lt;/strong&gt;, so now I can run this project from both the command line and with a single keystroke (&lt;code&gt;Ctrl+F5&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&quot;run-tests-with-nunit&quot;&gt;Run Tests With NUnit&lt;/h2&gt;
&lt;p&gt;This step requires some extra work and I had to hunt down the details. I naively installed something and didn’t know that it depended on something else and so on. I hope that this saves you some headache.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT
$ dotnet add package Microsoft.NET.Test.Sdk
$ dotnet add package Nunit3TestAdapter
$ dotnet add package NUnit
$ git add --all
$ git commit --message &amp;quot;We can now write and run tests with NUnit.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By installing all these packages into the project, I could run tests, at least from the command line. Almost.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ dotnet test
Program.cs(7,21): error CS0017: Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point. [$PROJECT_ROOT/$PROJECT_NAME.csproj]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I &lt;em&gt;believe&lt;/em&gt; that I only have one entry point, so I tried for a few minutes to figure out this message, but I gave up due to not finding anything simple and straightforward to read. Instead, I now simply remove &lt;code&gt;Program.cs&lt;/code&gt; and replace it with the code that I want to run, which contains tests.&lt;/p&gt;
&lt;p&gt;After doing that, I can run the tests.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ dotnet test
Build started, please wait...
Build completed.

Test run for $PROJECT_PATH/bin/Debug/netcoreapp2.1/$PROJECT_NAME.dll(.NETCoreApp,Version=v2.1)
Microsoft (R) Test Execution Command Line Tool Version 15.7.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
Failed   $FAILING_TEST_NAME
Error Message:
 System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Stack Trace:
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   [...]

Total tests: 9. Passed: 8. Failed: 1. Skipped: 0.
Test Run Failed.
Test execution time: 0.7209 Seconds&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can even run the tests in VS Code. I open the file containing the tests, wait a moment, and see &lt;strong&gt;Run All Tests&lt;/strong&gt; as an option beneath the &lt;code&gt;[TestFixture]&lt;/code&gt; annotation where I declare the test class. When I choose this option, VS Code runs the tests and reports the same results as &lt;code&gt;dotnet test&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With this, I feel satisfied. I can run tests.&lt;/p&gt;
&lt;h1 id=&quot;removing-it-all&quot;&gt;Removing It All&lt;/h1&gt;
&lt;p&gt;In order to remove all this stuff, this seems to suffice. First, I close VS Code. After that I issue these commands.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# Remove the project
$ rm -fr $PROJECT_ROOT
# Remove the VS Code user-level settings
$ rm -fr $DOTFILES/common/config/.config/Code
# Remove VS Code
$ sudo apt-get remove code
# Remove .NET SDK
$ sudo apt-get remove dotnet-sdk-2.1
# I probably want to keep this installed, but I don&amp;#39;t have enough experience to judge. I welcome your opinions.
$ sudo apt-get remove apt-transport-https
# I certainly want to remove the rest of this stuff!
$ sudo dpkg --remove packages-microsoft-prod
# I didn&amp;#39;t expect to need to do this. See &amp;quot;By The Way...&amp;quot; below.
$ sudo dpkg --purge packages-microsoft-prod
$ sudo apt-get update
$ sudo etckeeper commit &amp;quot;Removed .NET SDK, C#, and VS Code.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;future-work&quot;&gt;Future Work&lt;/h1&gt;
&lt;p&gt;I’m not planning to work in C# on VS Code in a professional setting, so this sufficed for me. Even so, I can imagine wanting to add at least the following.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run this entire setup in a container of some kind to isolate it from the rest of the system. Docker?&lt;/li&gt;
&lt;li&gt;Somebody must have built some kind of decent GUI test runner that runs inside VS Code to run these tests. What plays the role of Test-Driven .NET for VS Code?&lt;/li&gt;
&lt;li&gt;How do I organize the files in a C#/NUnit project? I presume that I want separate assemblies for production code and test code, so that I can ship the first without the second.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you can write or point to a tutorial that helps answer these questions, then please do. I would happily expand this tutorial to include information like that.&lt;/p&gt;
&lt;h1 id=&quot;by-the-way&quot;&gt;By The Way…&lt;/h1&gt;
&lt;p&gt;I learned something about &lt;code&gt;dpkg&lt;/code&gt; the hard way while preparing this tutorial: I don’t trust the word &lt;code&gt;remove&lt;/code&gt; in &lt;code&gt;dpkg --remove&lt;/code&gt; to mean “remove”, because it doesn’t necessarily remove things, at least according to my understanding of “remove”.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# I need to remove Microsoft&amp;#39;s package repository so that I can reinstall it for this tutorial.
$ sudo dpkg --remove packages-microsoft-prod
$ sudo rm /etc/apt/sources.list.d/microsoft-prod.list
# Now reinstall!
$ sudo dpkg --install $DOWNLOADS/packages-microsoft-prod.deb
$ sudo apt-get update
# Wait... I don&amp;#39;t see the Microsoft repository in the list. Hm.
$ sudo apt-get install dotnet-sdk-2.1
[&amp;quot;I&amp;#39;ve never heard of this &amp;#39;dotnet-sdk-2.1&amp;#39;.&amp;quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Strange. I expect &lt;code&gt;--remove&lt;/code&gt; to remove things. I guess not. After about 15 minutes of searching the web without even knowing which specific keywords would help me—I &lt;em&gt;love&lt;/em&gt; that—I stumble upon a clue examining the switches on &lt;code&gt;dpkg&lt;/code&gt;. I find a switch called &lt;code&gt;--purge&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Wait a moment! If &lt;code&gt;--remove&lt;/code&gt; removes things, then why do you need &lt;code&gt;--purge&lt;/code&gt;? This must mean that &lt;code&gt;--remove&lt;/code&gt; only &lt;em&gt;sometimes&lt;/em&gt; removes things or it removes things for some &lt;em&gt;weaker&lt;/em&gt; meaning of “remove”. I figured that it couldn’t hurt to try.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ sudo dpkg --purge packages-microsoft-prod
$ sudo dpkg --install $DOWNLOADS/packages-microsoft-prod.deb
$ sudo apt-get update
[Output that includes listing a repository with the name &amp;quot;microsoft&amp;quot; in it.]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;If you remove something with &lt;code&gt;dpkg&lt;/code&gt;, but it doesn’t seem to completely disappear, then try purging it.&lt;/strong&gt; If you understand this better, then please explain it in the comments so that I can improve this document.&lt;/p&gt;
</description>
        <pubDate>Sat, 21 Jul 2018 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/from-zero-to-nunit-with-visual-studio-code</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/from-zero-to-nunit-with-visual-studio-code</guid>
        
        
        <category>Tutorials</category>
        
      </item>
    
      <item>
        <title>Removing RVM Completely</title>
        <description>&lt;p&gt;I made a silly mistake installing &lt;code&gt;rvm&lt;/code&gt; on my new Linux laptop. I should mention that I don’t really know Linux yet, so that makes me susceptible to making this kind of silly mistake. I accidentally installed &lt;code&gt;rvm&lt;/code&gt; as a multi-user/system-wide tool, rather than in single-user mode. Since I like the &lt;em&gt;use the narrowest scope possible&lt;/em&gt;, I wanted to fix this. Of course I also had the problem that &lt;code&gt;rvm&lt;/code&gt; wouldn’t work without &lt;code&gt;sudo&lt;/code&gt; and that seemed really weird to me. I figured that I should uninstall &lt;code&gt;rvm&lt;/code&gt; completely and then start again. No problem, right?&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;I wanted to remove an accidental multi-user/system-wide installation of &lt;code&gt;rvm&lt;/code&gt; on Ubuntu 18.04. I removed all the files in my home directory as well as all the system directories. I removed the initialization commands from my login scripts. I still had some left over in my shell, even though I couldn’t find any script setting them. &lt;strong&gt;I had to reboot in order for those environment variables to disappear.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&quot;details&quot;&gt;Details&lt;/h1&gt;
&lt;p&gt;Most of the articles I read about how to completely uninstall &lt;code&gt;rvm&lt;/code&gt; assumed that I had a single-user installation, so they mostly didn’t help. I finally managed to figure out that I needed to delete all the following files/directories:&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$HOME/.rvm
$HOME/.rvmrc
/etc/rvmrc
/etc/profile.d/rvm.sh
/usr/share/rvm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also had to remove all trace of &lt;code&gt;rvm&lt;/code&gt; from my login shell scripts &lt;code&gt;.bashrc&lt;/code&gt; and &lt;code&gt;.zshrc&lt;/code&gt;. I did all this and then tried to reinstall &lt;code&gt;rvm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nope! When I reinstalled &lt;code&gt;rvm&lt;/code&gt; it seemed to have the same file permissions problems that led me to unknowingly install it with &lt;code&gt;sudo&lt;/code&gt; in the first place. After much too much fiddling around, I gradually understood that I probably had some extraneous environment variables somewhere, so I checked.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ env | grep rvm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sure enough, I had a handful of &lt;code&gt;rvm&lt;/code&gt;-related environment variables that affected how &lt;code&gt;rvm&lt;/code&gt; would install itself. I could simply &lt;code&gt;unset&lt;/code&gt; these environment variables, but I wanted to ensure that nothing would reset them, so I started to search for which script was setting these environment variables.&lt;/p&gt;
&lt;p&gt;None. Nothing. Nothing in my login shell scripts, nothing in &lt;code&gt;/etc/profile.d&lt;/code&gt;, nothing anywhere. Nothing. I spent an hour trying to find some magic trick to determine where these environment variable values came from. Nothing helped. Since I don’t know Linux/unix that well, I assumed that I didn’t know something important, so it took far too long before I fell back on some fundamental tricks of desperation.&lt;/p&gt;
&lt;p&gt;I logged out and logged back in. The environment variables were still there, even though nobody seemed to be setting them. This made no sense to me at all.&lt;/p&gt;
&lt;p&gt;Finally, in the greatest desperation, &lt;em&gt;I rebooted&lt;/em&gt;. This is Linux. I’m not supposed to need to do this. But it worked! I rebooted, I opened a fresh shell, I typed &lt;code&gt;env | grep rvm&lt;/code&gt; and got nothing!&lt;/p&gt;
&lt;p&gt;From here, I could follow the instructions to install &lt;code&gt;rvm&lt;/code&gt; for a single user the way I wanted it to work. And now it works. So far, nobody in my social media network has adequately explained why I needed to reboot in order to stop setting those environment variables in my shells.&lt;/p&gt;
&lt;p&gt;If you can explain why I needed to reboot in order for a fresh login shell session to stop setting these environment variables, then I would appreciate understanding how this could possibly happen. I don’t want to know, but I also don’t want to be flummoxed by it in the future. Leave a comment.&lt;/p&gt;
</description>
        <pubDate>Sat, 14 Jul 2018 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/removing-rvm-completely</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/removing-rvm-completely</guid>
        
        
        <category>The Little Things</category>
        
      </item>
    
      <item>
        <title>Who Tests the Contract Tests?</title>
        <description>&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/who-tests-the-contract-tests/stubs-and-expectations-and-spies-and-mocks-and-contract-tests.jpg&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;I write contract tests in order to help with the &lt;em&gt;drifting test doubles problem&lt;/em&gt;: how do I know that my stubs and expectations and spies and mocks behave “like the real thing”? I do this because contract tests run in less time than integrated tests, I feel more confident with passing contract tests than I do with integrated tests, and they help me document my understanding of the contracts of the code that I use.&lt;/p&gt;
&lt;p&gt;Unfortunately, it remains possible to write a contract test that contradicts a collaboration test. It remains possible to change a stub or an expectation or a spy or a mock and not notice that the new behavior doesn’t match the contract tests. It seems that this doesn’t fix the drifting test doubles problem after all. So what do I do? Who tests the contract tests?&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;If you try to use automated tools to write contract tests, you end up reimplementing a pre-runtime type checker. Note that &lt;strong&gt;this does not mean that&lt;/strong&gt; “therefore compile-time type checking is better”, but &lt;a href=&quot;https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule&quot;&gt;it does remind me of the old joke about LISP&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you choose not to write the contract tests now that matter most, then you will very probably need to reverse-engineer that knowledge at some unknown point in the future, likely when it feels least convenient. Make this trade consciously!&lt;/li&gt;
&lt;li&gt;If you &lt;em&gt;do&lt;/em&gt; plan to write the contract tests that matter most, and since automated tools can’t help you here, &lt;strong&gt;I encourage you to approach the work systematically&lt;/strong&gt;. This way, you can feel more confident that you’ve done it effectively and can reasonably expect to reap the benefits.
&lt;ul&gt;
&lt;li&gt;Match the stubs in your collaboration tests to “assert equals” checks in your contract tests.&lt;/li&gt;
&lt;li&gt;Match the expectations in your collaboration tests to actions in your contract tests.&lt;/li&gt;
&lt;li&gt;Writing code “client-first” means writing collaboration tests and building the test list for the contract tests associated with the next layer.&lt;/li&gt;
&lt;li&gt;Writing code “supplier-first” risks the Chunnel Problem: not knowing that you’ve built enough of the right things and only enough of the right things until you try to connect it to some clients; therefore, when in doubt, write code client-first.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And now, the details.&lt;/p&gt;
&lt;h2 id=&quot;the-two-parts-of-a-contract&quot;&gt;The Two Parts of a Contract&lt;/h2&gt;
&lt;p&gt;Not all contract tests provide the same level of confidence and safety, so it helps to talk more precisely about contract tests as a way to clarify where to focus your limited resources of time, energy, and money.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/who-tests-the-contract-tests/syntax-plus-semantics.jpg&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;I don’t know of any automated system (still, as of 2020) for verifying that collaboration tests (does a client use its neighbors correctly?) and contract tests (does a supplier behave as clients expect?) correspond to each other correctly—at least not the &lt;em&gt;truly interesting&lt;/em&gt; parts. For now, we need to check those things ourselves. In order to describe the truly interesting parts of a contract, let me introduce two useful terms.&lt;/p&gt;
&lt;div class=&quot;aside&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;When I say &lt;em&gt;the contract&lt;/em&gt;, I might mean the contract of a single function or of a cohesive group of functions (an interface or a protocol). The contract of a group of functions is includes the contracts of all the functions in it and maybe some interactions between those functions. Think about how size/empty or contains/indexOf need to behave consistently in order to make sense: these are examples of part of the contract of a protocol that goes beyond simply the contract of a single function. I’ll continue to refer to “the contract” in general, since the difference between a single function or a group a functions almost never matters.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A contract has two parts: its &lt;em&gt;syntax&lt;/em&gt; and its &lt;em&gt;semantics&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The syntax of a contract refers to the method signatures&lt;/strong&gt;: the names, parameter types, return value type, and any exceptions it might throw. I think of the syntax as the &lt;em&gt;shape&lt;/em&gt; of the interface. We check the syntax of a contract in order to feel confident that &lt;strong&gt;clients and suppliers will fit together&lt;/strong&gt;. In a language that checks types at compile time (Java, C#, C, C++), the compiler checks for syntax mismatches, so if the (client) code compiles, then we have some protection against syntax mistakes. (The amount of protection depends on the precision of the types available.) In a language that checks types at run time (Ruby, Python, Smalltalk, Javascript), then we don’t discover syntax mismatches until we see “method missing” or “key error” or &quot;undefined. (Different languages give us different clues about syntax mismatches.) When I feel confident that components agree on the syntax of a contract, I feel confident that those components will at least talk to each other correctly, even if the conversation they have might not make sense and they might collectively do the wrong thing. In languages with more-precise type systems, getting the syntax right provides significant confidence that we’ve got the behavior right.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The semantics of a contract refers to the rules of behavior&lt;/strong&gt;: how inputs map to outputs, which side-effects are expected or permitted, and rules for throwing exceptions. I think of the semantics as the “working agreements” between client and supplier. We check the semantics of a contract in order to check that &lt;strong&gt;clients and suppliers will work together&lt;/strong&gt;. When I feel confident that components agree on the semantics of a contract, I feel confident that those components will behave sensibly together. They might solve the wrong problem, but they will fail only when they should and they will succeed when they should. &lt;strong&gt;With this level of confidence, clients can freely choose the appropriate suppliers to help them solve a specific domain problem&lt;/strong&gt; without worrying about whether the suppliers might do something unexpected, even if we can’t yet conclude that the clients are trying to solve the right domain problem.&lt;/p&gt;
&lt;h2 id=&quot;collaboration-tests-need-clear-contracts&quot;&gt;Collaboration Tests Need Clear Contracts&lt;/h2&gt;
&lt;p&gt;When I imagine a collaboration test—even before I type it into the computer—I need details about the contracts of the suppliers with which the subject under test interacts. When I write code client-first, I am designing those contracts; when I connect a new client to existing suppliers, I need clear expectations about how those suppliers behave. &lt;strong&gt;In most situations I’m making assumptions about the contracts of the subject’s collaborators&lt;/strong&gt;, either that I’ll find a way to make those collaborators behave that way or that I recall correctly how they behave. I need to check these assumptions somehow.&lt;/p&gt;
&lt;p&gt;I write contract tests in order to document the contracts of suppliers so that I can confidently write collaboration tests for the clients of those suppliers. &lt;strong&gt;The drifting test doubles problem happens exactly when programmers write collaboration tests without a clear understanding of the contracts of the subject’s collaborators&lt;/strong&gt;. This lack of clarity leaves them searching for a way to bridge the gap. Many of them turn to integrated tests to check the assumptions in their collaboration tests. &lt;strong&gt;I recommend against using integrated tests this way.&lt;/strong&gt; This way lies the &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests scam&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;aside&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;I would say that any sufficiently-complicated integrated test suite is a haphazard, defect-masking, difficult-to-follow, bloated (duplication-infested) suite of contract tests.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;how-not-to-paint-a-wall&quot;&gt;How Not To Paint A Wall&lt;/h2&gt;
&lt;p&gt;Imagine that you need to paint a wall. (It’s not my fault that you need to paint a wall. Here we are.) Not a small wall—a few metres tall and several metres wide. You probably use some combination of paint rollers for the easy parts of the wall and paint brushes for the corners. You probably put masking tape along the edges of the wall in order to help yourself paint only the parts of the wall that you want to paint. You might use an edger, but some people find them a bit difficult to control and, in the end, not faster than a conventional small brush. You probably do the same around the electrical outlets, any doorways, or any other part of the wall that you don’t want to paint. In other words, &lt;strong&gt;you use precision tools to paint the wall when you need precision and you use less-precise tools to paint the larger portions of the wall where you don’t have to worry as much about precision&lt;/strong&gt;. All this probably sounds quite sensible to you.&lt;/p&gt;
&lt;p&gt;Now imagine your friend who has a different approach. They line up a bunch of cans of paint three metres away from the wall. They stand there, staring at the wall a moment in preparation. Next, they pick up a can and throw paint at the wall. Some paint sticks to the wall. Maybe even &lt;em&gt;a lot&lt;/em&gt; of the paint sticks to the wall. Maybe your friend is world paint-throwing champion and manages to get most of the paint to stick to mostly the right parts of the wall. So far, so good, but what about the corners? What about avoiding the electrical outlets and the windows? How do they get paint in the very top-left corner of the wall, some five or six metres away? That’s a long way to throw paint so accurately and precisely. They keep picking up buckets of paint and throwing them at the wall. The central parts of the wall end up with many coats of paint (how many? nobody knows) and the corners with very little. &lt;strong&gt;No matter how long they keep throwing paint at the wall, the corners never seem to get any paint&lt;/strong&gt;, and they might as well stop. The whole thing seems very haphazard. At some point, you probably want to yell at your friend to pick up a brush to paint the corners!&lt;/p&gt;
&lt;p&gt;I feel exactly this way about using integrated tests to check your understanding of the contracts between clients and suppliers throughout the system. &lt;strong&gt;By putting all the components together and running them in a single test, you’re throwing tests at the system, hoping to cover the whole thing&lt;/strong&gt;. You’re also covering certain parts of the system much more than you need to and missing other parts entirely. Even if you manage to cover 30% to 70% of the system relatively quickly this way, I can’t tell what you’ve covered and what you haven’t. As long as you insist on throwing tests at the system, you’ll miss significant parts of the system and you won’t really know which parts you’ve missed until a customer reports a problem. Pick up a brush and paint the corners already!&lt;/p&gt;
&lt;p&gt;Contract tests help me cover the wall evenly and completely.&lt;/p&gt;
&lt;p&gt;Sadly, contract tests alone don’t solve the drifting problem; but they remind us of the risk in a way that integrated tests just don’t seem to do for most people most of the time. I believe that this results from how utterly distracting integrated tests become over time: riddled with duplicated, mostly-irrelevant details. Yes, yes, the current user needs to have logged in! Yes, yes, we have to put this big heap of magic data into the database, because of all the foreign key constraints! Yes, yes, we have to tweak that configuration file, changing one or two settings out of the 118 settings it contains! &lt;strong&gt;These details assault our senses and beat our conscious minds into submission&lt;/strong&gt;. Our eyes glaze over. Before long, we stop paying attention. &lt;strong&gt;Over time it becomes easier, not harder, to make a mistake&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;collaboration-tests-and-contract-tests-check-each-other&quot;&gt;Collaboration Tests And Contract Tests Check Each Other&lt;/h2&gt;
&lt;p&gt;We can use automated tools to address the drifting problem for the &lt;em&gt;syntax&lt;/em&gt; of contracts, but not for the semantics. You can already find libraries that help detect interface syntax changes in languages that don’t have compile-time type checking. These include &lt;a href=&quot;https://github.com/robindanzinger/chadojs&quot;&gt;chado&lt;/a&gt; for Javascript and &lt;a href=&quot;https://github.com/realestate-com-au/pact&quot;&gt;Pact&lt;/a&gt; for Ruby, or whatever the cool kids are using these days. &lt;strong&gt;These libraries effectively provide a form of pre-runtime type checking&lt;/strong&gt; to help alert the programmer to potential incompatibilities between collaboration tests and the syntax of the contract of the collaborators. We can also add type checking to languages that don’t have it built in, which explains why we have Typescript. The semantics of a contract, however, require more complicated and varied checks. They describe the meaning and purpose of the modules in the system. I don’t know of any software that can write those checks for us. A human needs to do that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I maintain the correspondence between collaboration tests and contract semantics tests by hand&lt;/strong&gt;. I don’t know of any automated way to do this. Building software to help with this task sounds like a suitable Ph. D. project—indeed, a few people have told me that they intended to do exactly that, but I haven’t seen any results yet (still not, as of 2020).&lt;/p&gt;
&lt;h2 id=&quot;my-system&quot;&gt;My System&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;paragraph-eyecatcher&quot; src=&quot;/images/who-tests-the-contract-tests/correspondences-between-tests.jpg&quot;&gt;&lt;/img&gt;&lt;/p&gt;
&lt;p&gt;Rather than throw paint at the wall, let me describe what I do, which corresponds to painting the corners of the wall with a brush.&lt;/p&gt;
&lt;p&gt;First, I describe the key properties of collaboration and contract tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;stub&lt;/strong&gt; in a collaboration test corresponds to the &lt;strong&gt;expected result&lt;/strong&gt; of an assertion in a contract test.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;expectation&lt;/strong&gt; in a collaboration test corresponds to the &lt;strong&gt;action&lt;/strong&gt; of a contract test.&lt;/li&gt;
&lt;li&gt;These correspondences apply equally well in both directions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From this, we can extract some helpful rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When I write a stub in a collaboration test, then I remind myself to also write a contract test where the stubbed return value becomes the expected result of the contract test.&lt;/li&gt;
&lt;li&gt;When I write a contract test with &lt;code&gt;assert_equals()&lt;/code&gt; in it, then I can safely stub that method to return that value in a collaboration test. Moreover, I should probably try to imagine a collaboration test for the client that stubs that method to return that value so as to document what happens in that case. Maybe I need it; maybe I don’t.&lt;/li&gt;
&lt;li&gt;When a collaboration test expects a method (with certain parameters), then I remind myself to also write a contract test that describes what happens when we invoke that method with those parameters. Any module that implements that method must behave accordingly.&lt;/li&gt;
&lt;li&gt;When I write a contract test with the action &lt;code&gt;foo(a, b, c)&lt;/code&gt; in it, then I can safely write a collaboration test that expects (“mocks”) &lt;code&gt;foo(a, b, c)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I should mention that the method parameters don’t need to match &lt;em&gt;exactly&lt;/em&gt;, but they do need to come from the same &lt;a href=&quot;https://en.wikipedia.org/wiki/Equivalence_class&quot;&gt;class of equivalence&lt;/a&gt;. If you feel unsure how to start, then start by making the method parameters match the contract test values exactly.&lt;/p&gt;
&lt;p&gt;I have built a system out of following these rules to replace the haphazard approach of writing integrated tests until it somehow feels safe enough. My system requires more care and attention than throwing tests at the problems, but I can make more-well-informed tradeoff decisions between writing the contract tests now or reverse-engineering that knowledge later. By relying on integrated tests, I don’t even know how much of a risk I’m taking; but by thinking about the contract test that corresponds to this collaboration test, I have a clearer picture of the risk I’m taking by thinking &lt;em&gt;No, it’s fine. I understand this well enough. The corresponding contract test is obvious.&lt;/em&gt; I might still not write the contract test, but this additional precision provides just enough resistance to challenge my assumption about how obvious or self-evident or clear the contract will seem to whoever needs to read this code weeks, months, or years from now. &lt;strong&gt;Even if I get this wrong, we will know better how to fill in the gaps in the contract tests when we finally get around to writing them&lt;/strong&gt;. Maintaining the correspondence between collaboration and contract tests better assures me that I have agreement between clients and suppliers. It helps with both the syntax and semantics of my interfaces. When I finally put things together, they not only fit, but they just work.&lt;/p&gt;
&lt;h2 id=&quot;but-what-about-the-domain-problem&quot;&gt;But… What About The Domain Problem?&lt;/h2&gt;
&lt;p&gt;This system helps me feel justifiably confident about how well the code fits together (syntax) and works together (semantics), but it doesn’t (alone) guarantee that the resulting system solves the intended domain problem. For that, I need customer tests, and I will probably write most of those customer tests as end-to-end tests.&lt;/p&gt;
&lt;p&gt;Yes—I hear you screaming. Stay with me a little longer.&lt;/p&gt;
&lt;p&gt;I often use a smaller number of customer-facing integrated tests to help the &lt;em&gt;customer&lt;/em&gt; feel confident that we programmers have understood what they need, but &lt;strong&gt;I definitely do not rely on an ever-growing suite of integrated tests to help the programmers feel confident that the system “hangs together” correctly&lt;/strong&gt;. On the contrary, since I write collaboration and contract tests, &lt;strong&gt;my customer tests rarely fail due to incorrect code&lt;/strong&gt;, but rather due to differences of understanding about the business problem that we need to solve. &lt;strong&gt;This makes those customer tests much more effective as tools for guiding the development of a system&lt;/strong&gt;. It also helps the customer see those tests as providing evidence of progress. It helps the customer feel confident in those tests. It helps them &lt;em&gt;believe&lt;/em&gt; and &lt;em&gt;trust&lt;/em&gt; those tests. That makes the project go more smoothly.&lt;/p&gt;
&lt;h2 id=&quot;my-fellow-programmers-wont-do-this&quot;&gt;“My Fellow Programmers Won’t Do This”&lt;/h2&gt;
&lt;p&gt;I understand! Not every programmer volunteers to work with the same level of discipline in the same facets of their work as I do. Even if they did, not every programmer would believe that this approach works better than writing integrated tests. Some programmers insist on painting a wall from three metres back. I understand why they might prefer it (it seems easier), but I’ll never understand why they consider it more &lt;em&gt;effective&lt;/em&gt; than picking up a brush. If you decide that you prefer to paint the wall with rollers and brushes and your fellow programmers try to stop you, then you have an entirely different problem. &lt;a href=&quot;https://experience.jbrains.ca&quot;&gt;Maybe I can help with that, too.&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Lisa Crispin, &lt;a href=&quot;https://lisacrispin.com/2011/11/08/using-the-agile-testing-quadrants/&quot;&gt;“Using the Agile Testing Quadrants”&lt;/a&gt;. An overview of classifying tests as a way to clarify their nature and purpose. I use this model here briefly to refer to customer-facing (also known as “business-facing”) tests as separate from technology-facing tests.&lt;/p&gt;
&lt;p&gt;Brian Marick, &lt;a href=&quot;https://www.exampler.com/old-blog/2003/08/21.1.html#agile-testing-project-1&quot;&gt;“Agile Testing Directions”&lt;/a&gt;. A series of articles describing a systematic approach to testing in an iterative and incremental environment that one might label as Lightweight or Agile (as it was meant to be practiced).&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Jul 2018 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/who-tests-the-contract-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/who-tests-the-contract-tests</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>I Learned Some sed</title>
        <description>&lt;section class=&quot;highlight&quot;&gt;
&lt;p&gt;In 2022 I learned about &lt;code&gt;sd&lt;/code&gt;, a modern replacement for many of the simplest ways to use &lt;code&gt;sed&lt;/code&gt;. &lt;a href=&quot;https://github.com/chmln/sd&quot;&gt;Check it out!&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;p&gt;I decided to learn a little &lt;code&gt;sed&lt;/code&gt;, because I can find it everywhere and it seems like the kind of tool that would make a bunch of everyday things easier and faster.&lt;/p&gt;
&lt;p&gt;I started with &lt;a href=&quot;https://www.grymoire.com/Unix/Sed.html&quot;&gt;“Sed - An Introduction and Tutorial by Bruce Barnett”&lt;/a&gt; and immediately realized the enormity of the consequences of my choice.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Anyhow, &lt;em&gt;sed&lt;/em&gt; is a marvelous utility. Unfortunately, most people never learn its real power. The language is very simple, but the documentation is terrible. The Solaris on-line manual pages for sed are five pages long, and two of those pages describe the 34 different errors you can get. A program that spends as much space documenting the errors as it does documenting the language has a serious learning curve. — “Sed — An Introduction and Tutorial”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you can read this, then I didn’t abandon ship.&lt;/p&gt;
&lt;h2 id=&quot;the-essential-command&quot;&gt;The Essential Command&lt;/h2&gt;
&lt;p&gt;Evidently, my world in &lt;code&gt;sed&lt;/code&gt; will revolve around the command &lt;code&gt;s&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ echo day | sed &amp;quot;s/day/night/&amp;quot;
night&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That seems reasonable enough. This might even provide as much as I need for my current task.&lt;/p&gt;
&lt;h2 id=&quot;my-current-task&quot;&gt;My Current Task&lt;/h2&gt;
&lt;p&gt;I have started redesigning this very web site. (You might even be reading this article on the redesigned version of the web site.) As of the end of 2017, I used Jekyll to generate this site. When I started using Jekyll, I took advantage of Jekyll’s built in feature for generating &lt;em&gt;excerpts&lt;/em&gt; from articles. Later, when someone taught me about Twitter cards for promoting my articles better, I began needing &lt;em&gt;summaries&lt;/em&gt; in addition to &lt;em&gt;excerpts&lt;/em&gt;. Now, I realize that I don’t need excerpts at all, really, and so I want to change excerpts to summaries.&lt;/p&gt;
&lt;p&gt;This involves changing article metadata, stored in YAML. I need to rename the &lt;code&gt;excerpt&lt;/code&gt; property to &lt;code&gt;summary&lt;/code&gt;. As far as I can tell, I don’t need to change anything else. This means that it suffices to change the string &lt;code&gt;excerpt&lt;/code&gt; to &lt;code&gt;summary&lt;/code&gt;, as long as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it occurs at the beginning of a line, and&lt;/li&gt;
&lt;li&gt;a colon (&lt;code&gt;:&lt;/code&gt;) follows it, and&lt;/li&gt;
&lt;li&gt;it occurs within the YAML front matter, which comes between lines of &lt;code&gt;\-\-\-&lt;/code&gt; at the beginning of the document&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It seems highly unlikely that I’d find the word &lt;code&gt;excerpt&lt;/code&gt; at the beginning of a line, followed by a colon, but occurring in the main text of the article, so I can probably very safely ignore the last of these conditions; however, I might as well learn how to handle it with &lt;code&gt;sed&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;sed&lt;/code&gt; works on one line at a time, I need a stateful solution that effectively remembers “I’ve entered the YAML front matter” and “I’ve left the YAML front matter”. Or something like that. Let’s see….&lt;/p&gt;
&lt;h2 id=&quot;a-simplified-solution&quot;&gt;A Simplified Solution&lt;/h2&gt;
&lt;p&gt;If I permit myself temporarily to ignore the condition of matching text inside the front matter, then I can transform &lt;code&gt;excerpt&lt;/code&gt;s into &lt;code&gt;summary&lt;/code&gt;s in a fairly straightforward way. Doing this will allow me to learn how to operate on a family of files without simultaneously trying to understand more-complicated &lt;code&gt;sed&lt;/code&gt; syntax, so let me start there.&lt;/p&gt;
&lt;p&gt;I know how to perform a single regex replacement, so I start there.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT  # Where my Jekyll project resides
$ grep -r &amp;quot;^excerpt&amp;quot; source/**
[A list of article files with excerpts.]
$ cat source/_posts/2010-01-28-not-just-slow-integration-tests-are-a-vortex-of-doom.markdown | sed &amp;quot;s/^excerpt:/summary:/&amp;quot;
[The output of the article, but with &amp;quot;summary:&amp;quot; instead of &amp;quot;excerpt:&amp;quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I’d like to change the file “in place”. Since I have put these files in version control, I can safely change them in place, and then check them out if I accidentally destroy them. For that, I need the &lt;code&gt;-i&lt;/code&gt; switch.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT
$ sed -i &amp;quot;s/^excerpt:/summary:/&amp;quot; source/_posts/2010-01-28-not-just-slow-integration-tests-are-a-vortex-of-doom.markdown
sed: 1: &amp;quot;source/_posts/2010-01-2 ...&amp;quot;: bad flag in substitute command: &amp;#39;t&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nope! Nice try. But wait… &lt;em&gt;why not&lt;/em&gt;?!&lt;/p&gt;
&lt;p&gt;Aha.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The GNU version of sed allows you to use “-i” without an argument. The FreeBSD/Mac OS X does not. You must provide an extension for the FreeBSD/Mac OS X version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since I find myself on Mac OS X, I have to provide an argument to &lt;code&gt;-i&lt;/code&gt;: a “backup” file extension to which &lt;code&gt;sed&lt;/code&gt; can rename the file that it changes in place. And since I don’t want to create a backup…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you want to do in-place editing without creating a backup, you can use &lt;code&gt;sed -i \&apos;\&apos;  \&apos;s/\^/\t/\&apos;  *.txt&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Silly, but then, Bruce warned me.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT
$ sed -i &amp;#39;&amp;#39; &amp;quot;s/^excerpt:/summary:/&amp;quot; source/_posts/2010-01-28-not-just-slow-integration-tests-are-a-vortex-of-doom.markdown
[No output. I assume this means that all went well.]
$ echo $?
0  # an exit code of 0 means that my command threatened to work
$ git diff
[Evidence that only the excerpt metadata property changed. Success!]
$ git reset --hard HEAD   # Let me now try to change all the articles at once!
$ sed -i &amp;#39;&amp;#39; &amp;quot;s/^excerpt:/summary:/&amp;quot; source/_posts/**/*.{markdown,md}
[No output. I don&amp;#39;t trust myself just yet.]
$ echo $?
0   # Wow!
$ git diff --stat
[Evidence that I changed 14 files.]
$ grep -r &amp;quot;^excerpt&amp;quot; source/**
[Evidence that no files inside source/ have an excerpt metadata property.]
$ git add -A
$ git commit -m &amp;quot;Articles now provides summaries for Twitter cards, instead of legacy excerpts.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Very nice!&lt;/p&gt;
&lt;h2 id=&quot;a-more-precise-solution&quot;&gt;A More-Precise Solution&lt;/h2&gt;
&lt;p&gt;Now, I can set a timer for 15 minutes and try to learn a &lt;em&gt;more-precise&lt;/em&gt; solution, which only matches &lt;code&gt;excerpt&lt;/code&gt; inside the YAML front matter, instead of anywhere else in the article. In order to do this, I need to create an article with &lt;code&gt;excerpt:&lt;/code&gt; at the beginning of a line in the main body of the article. Since I don’t actually want any such article published to this blog, I create a version control branch that I can easily throw away.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT
$ git checkout -b learn-advanced-sed HEAD^
$ grep -r &amp;quot;^excerpt&amp;quot; source/** | wc -l
      14   # As I inferred from having changed 14 files in the previous step.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I create an “article” that I can use to challenge my &lt;code&gt;sed&lt;/code&gt;-fu.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT
$ cat source/_posts/2017-12-22-a-stupid-article.md
---
title: &amp;quot;A Stupid Article&amp;quot;
date: 2017-12-22
excerpt: &amp;gt;
  This is an actual excerpt.
---
excerpt: Don&amp;#39;t put &amp;quot;excerpt:&amp;quot; at the beginning of a line in the actual article, you nit!
$ git add -A &amp;amp;&amp;amp; git commit -m &amp;quot;We now have an article that can test our sed-fu.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, if I try to use my existing solution, I’ll “accidentally” change too many lines.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT
$ sed -i &amp;#39;&amp;#39; &amp;quot;s/^excerpt:/summary:/&amp;quot; source/_posts/**/*.{markdown,md}
$ git diff --stat | grep -i &amp;quot;a-stupid-article&amp;quot;
 source/_posts/2017-12-22-a-stupid-article.md                          | 4 ++--
[Oops. I should have only added 1 line and deleted 1 line.]
$ git reset --hard HEAD&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So how do I find a range of lines? According to Bruce’s article, I can use a syntax familiar to &lt;code&gt;vim&lt;/code&gt; users: &lt;code&gt;start,stop&lt;/code&gt;. I can use regexes for &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; by using the typical &lt;code&gt;/regex/&lt;/code&gt; syntax. For YAML front matter, I want to look between the first two lines that start with three hyphens, so that means &lt;code&gt;/\^\-\-\-/,/\^\-\-\-/&lt;/code&gt;. Does it work?&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $BLOG_PROJECT_ROOT
$ sed -i &amp;#39;&amp;#39; &amp;quot;/^---/,/^---/ s/^excerpt:/summary:/&amp;quot; source/_posts/**/*.{markdown,md}
[No output. I don&amp;#39;t trust the silence.]
$ echo $?
0
$ git diff --stat | grep -i &amp;quot;a-stupid-article&amp;quot;
 source/_posts/2017-12-22-a-stupid-article.md                            | 2 +-
[No way! It worked! Did it work everywhere?]
$ git diff --stat | grep &amp;quot;2 +-&amp;quot; | wc -l
      15
[Excellent! Just one last thing to check...]
$ git diff source/_posts/2017-12-22-a-stupid-article.md
diff --git a/source/_posts/2017-12-22-a-stupid-article.md b/source/_posts/2017-12-22-a-stupid-article.md
index d6863a1..5b51b1c 100644
--- a/source/_posts/2017-12-22-a-stupid-article.md
+++ b/source/_posts/2017-12-22-a-stupid-article.md
@@ -1,7 +1,7 @@
 ---
 title: &amp;quot;A Stupid Article&amp;quot;
 date: 2017-12-22
-excerpt: &amp;gt;
+summary: &amp;gt;
   This is an actual excerpt.
 ---
 excerpt: Don&amp;#39;t put &amp;quot;excerpt:&amp;quot; at the beginning of a line in the actual article, you nit!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Excellent! It works! And with 1 minute, 32 seconds left on the timer.&lt;/p&gt;
&lt;h2 id=&quot;the-winning-command&quot;&gt;The Winning Command&lt;/h2&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ sed -i &amp;#39;&amp;#39; &amp;quot;/^---/,/^---/ s/^excerpt:/summary:/&amp;quot; source/_posts/**/*.{markdown,md}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let me review the salient parts of this command.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-i \&apos;\&apos;&lt;/code&gt;: change the file “in place”, backing up the original file to “nowhere”. On other operating systems, you might only need to specify &lt;code&gt;-i&lt;/code&gt; without an argument.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;/\^\-\-\-/,/\^\-\-\-/ [\.\.\.]&quot;&lt;/code&gt;: apply the following command to only the region between the first occurrence of a line starting with &lt;code&gt;\-\-\-&lt;/code&gt; and the following line starting with &lt;code&gt;\-\-\-&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&quot;[\.\.\.] s/\^excerpt:/summary:/&quot;&lt;/code&gt;: replace &lt;code&gt;excerpt:&lt;/code&gt; (only when a line starts with it) with &lt;code&gt;summary:&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;source/_posts/**/*.{markdown,md}&lt;/code&gt;: this part uses &lt;code&gt;zsh&lt;/code&gt; to match all the files inside &lt;code&gt;source/_posts&lt;/code&gt;, including subfolders, with the extension &lt;code&gt;markdown&lt;/code&gt; or &lt;code&gt;md&lt;/code&gt;. This has nothing to do with &lt;code&gt;sed&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;some-notes&quot;&gt;Some Notes&lt;/h3&gt;
&lt;p&gt;According to Bruce’s article, my winning command would fail in an article with more than one pair of lines starting with &lt;code&gt;\-\-\-&lt;/code&gt;. I didn’t bother to test this. Also, Bruce’s tutorial notes that the substitution command applies to the boundary lines themselves, which happens not to affect my winning command.&lt;/p&gt;
&lt;h1 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/ianjmacintosh/status/946065347689541632&quot;&gt;A nice reader pointed out a mistake in an earlier draft of this article&lt;/a&gt;, and then &lt;a href=&quot;https://twitter.com/ianjmacintosh/status/946073116404576256&quot;&gt;reminded me that I could have used &lt;code&gt;sed&lt;/code&gt; to fix the mistake&lt;/a&gt;. Even though I had already published a fix for the mistake, I felt that I needed to go back and do it again with &lt;code&gt;sed&lt;/code&gt;, so I did. I had forgot to put &lt;code&gt;https://&lt;/code&gt; at the beginning of a URL, which makes Jekyll incorrectly interpret the URL as a URI at the blog’s server address. With &lt;code&gt;sed&lt;/code&gt;, this becomes a relatively easy command: &lt;code&gt;sed -i &apos;&apos; &quot;s/(www.grymoire/(https:\/\/www.grymoire/g&quot; source/_posts/*i-learned-some-sed*.md&lt;/code&gt;. I chose to include the open parenthesis &lt;code&gt;(&lt;/code&gt; in the search regex in order to narrow down the context. I didn’t need to do that, but it didn’t hurt.&lt;/p&gt;
&lt;p&gt;Even better, I might have started a trend:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
You inspired me to try out sed on my own because I was skeptical about those unescaped parens. I learned something!
&lt;/p&gt;
— Ian MacIntosh (&lt;span class=&quot;citation&quot; data-cites=&quot;ianjmacintosh&quot;&gt;@ianjmacintosh&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/ianjmacintosh/status/946163583653695488?ref_src=twsrc%5Etfw&quot;&gt;December 27, 2017&lt;/a&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Bruce Barnett, &lt;a href=&quot;https://www.grymoire.com/Unix/Sed.html&quot;&gt;“Sed - An Introduction and Tutorial”&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Fri, 22 Dec 2017 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/i-learned-some-sed</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/i-learned-some-sed</guid>
        
        
        <category>Tutorials</category>
        
        <category>Microtechniques</category>
        
      </item>
    
      <item>
        <title>Keep Dependency Injection Simple</title>
        <description>&lt;p&gt;I taught evolutionary design &lt;em&gt;in person&lt;/em&gt; to about 200 programmers this year.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; In the 15 years that I’ve been doing this, I’ve spoken with confused programmers who felt unsure how to use &lt;em&gt;dependency injection&lt;/em&gt; to improve their design. I tend to notice this confusion more often among the programmers who have “some experience” practising test-driven development—say, 6 months to 2 years. I’d like to share a few short pieces of advice, and if this advice leads you to ask some follow-up questions, then I invite you &lt;a href=&quot;https://ask.jbrains.ca&quot;&gt;ask them&lt;/a&gt;, so that I can help you even more.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why do I inject dependencies?&lt;/strong&gt; I have at least &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;one mechanical reason and one intuitive reason&lt;/a&gt; to inject dependencies. Injecting dependencies helps me write smaller, more-focused tests. A &lt;em&gt;smaller&lt;/em&gt; test runs less of the system and a &lt;em&gt;more-focused&lt;/em&gt; test involves fewer irrelevant details in the tests. The more I remove distractions from my tests, the more-easily I understand them, so &lt;strong&gt;they help me change the code, rather than get in my way&lt;/strong&gt; when I want to change code. In addition, when I inject dependencies, this allows me to check a client’s behavior without knowing details of the behavior of its suppliers. This helps me separate unrelated responsibilities, which leads to the usual benefits of higher cohesion: lower risk of distraction when I want to understand some specific part of the system and &lt;a href=&quot;/permalink/how-reuse-happens&quot;&gt;more opportunities to reuse code in other contexts&lt;/a&gt;. Injecting dependencies helps me in at least both of these significant ways.&lt;/p&gt;
&lt;p&gt;In my travels, when I ask programmers why they inject dependencies, I find out that most of them merely follow the rule that someone had taught them. &lt;a href=&quot;/permalink/guard-rails-not-prison-bars&quot;&gt;This works fine for learning&lt;/a&gt;, but I fear that many of these programmers have stopped learning (about this in particular), but continue to follow the rule. This has led to at least two unfortunate misconceptions that I’d like to clear up.&lt;/p&gt;
&lt;h2 id=&quot;unfortunate-misconceptions-about-dependency-injection&quot;&gt;Unfortunate Misconceptions About Dependency Injection&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;“I need to use dependency injection containers or frameworks.”&lt;/strong&gt; I don’t, and I don’t plan to. I’ve taken superficial looks at Guice and Dagger and &lt;strong&gt;I still have no idea what problem they solve&lt;/strong&gt;. I have, however, seen &lt;strong&gt;programmers use both frameworks and then proceed to do the exact opposite of injecting dependencies&lt;/strong&gt;: since it takes so much extra work to wire arbitrarily implementations together, they simply “reuse” the existing production-caliber modules and &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;write integrated tests for everything&lt;/a&gt;. This defeats one of my key purposes for injecting dependencies: writing smaller, more-focused tests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“If I use dependency injection, then I need to use Factories.”&lt;/strong&gt; Programmers in &lt;a href=&quot;https://training.jbrains.ca&quot;&gt;my training courses&lt;/a&gt; assume that injecting dependencies means that they (always?) need Factories to instantiate implementations. This assumption really puzzles me; I don’t know where it comes from. I occasionally use Factories, most often &lt;a href=&quot;/permalink/getting-started-with-contract-tests&quot;&gt;in contract tests&lt;/a&gt; (at least in JUnit); but otherwise, &lt;strong&gt;I simply instantiate implementations directly and pass them where I need them&lt;/strong&gt;. I rarely need Factories in production code as a result of injecting dependencies. (I use them for other reasons, usually as the Abstract Factory pattern.) When I combine this with &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;moving details towards the client&lt;/a&gt;, my designs improve considerably: the entry point decides how to wire implementations together and then injects that module graph into whatever framework I use to receive requests: web, CLI, service bus, it all works the same.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/permalink/injecting-dependencies-doesnt-have-to-hurt&quot;&gt;You can benefit from injecting dependencies without creating extra work&lt;/a&gt;. Pick some small corner of your code base and try ripping out all the container and framework stuff. Examine what remains. What do you think?&lt;/p&gt;
&lt;p&gt;Most importantly (for me), if you love dependency injection containers, then please share your reasons and your experiences. I’d like to understand this point, and nobody has managed to explain it to me in over a decade.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/refactor-your-way-to-a-dependency-injection-container&quot;&gt;“Refactor Your Way to a Dependency Injection Container”&lt;/a&gt;. Bespoke, artisanal containers. No, really.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/getting-started-with-contract-tests&quot;&gt;“Getting Started with Contract Tests”&lt;/a&gt;. I find it hard to inject dependencies without eventually wanting to write contract tests.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/injecting-dependencies-doesnt-have-to-hurt&quot;&gt;“Injecting dependencies doesn’t have to hurt”&lt;/a&gt;. This seems to be the 2010 version of this article. I hope the modern version provides more value; otherwise, I need to go stare in a mirror for a few hours and contemplate my life choices.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I think of &lt;em&gt;test-driven development&lt;/em&gt; as the implementation and &lt;em&gt;evolutionary design&lt;/em&gt; as the interface.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 10 Dec 2017 07:42:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/keep-dependency-injection-simple</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/keep-dependency-injection-simple</guid>
        
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Renaming Magically With zmv</title>
        <description>&lt;p&gt;I just learned about &lt;code&gt;zmv&lt;/code&gt; and I love it. If you already know about &lt;code&gt;zmv&lt;/code&gt; or you already love &lt;code&gt;rename&lt;/code&gt;, then don’t waste your time reading this.&lt;/p&gt;
&lt;p&gt;Sometimes I want to rename a bunch of files in a way that &lt;code&gt;mv&lt;/code&gt; can’t handle. Most recently, I had a bunch of files with the same name in numbered directories (&lt;code&gt;Page0/shot.jpg&lt;/code&gt;, &lt;code&gt;Page1/shot.jpg&lt;/code&gt;, …), and I wanted numbered files instead (&lt;code&gt;shot-0.jpg&lt;/code&gt;, &lt;code&gt;shot-1.jpg&lt;/code&gt;, …). Plain globbing won’t do it. (If it will and I don’t know how, then &lt;a href=&quot;https://tell.jbrains.ca&quot;&gt;please tell me&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;If you know about &lt;code&gt;rename&lt;/code&gt;, then this might bore you. I never learned about it.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;love&lt;/em&gt; &lt;a href=&quot;https://www.publicspace.net/ABetterFinderRename/index.html&quot;&gt;“A Better Finder Rename”&lt;/a&gt;, which I use on MacOS to rename files in batch. It provides a nice user experience for renaming a batch of files: drag a bunch of files into a basket, apply a bunch of transformations to the filenames and paths, get a preview of the resulting filename, and then press “Rename All” and watch all the renames happen. Very nice. I like the friendly user interface for composing complicated transformations.&lt;/p&gt;
&lt;p&gt;Sometimes, however, I have a simpler transformation in mind and I’d like to just use the command line. With &lt;code&gt;zmv&lt;/code&gt;, I can do this.&lt;/p&gt;
&lt;h2 id=&quot;what-you-need&quot;&gt;What You Need&lt;/h2&gt;
&lt;p&gt;For &lt;code&gt;zmv&lt;/code&gt;, you need &lt;code&gt;zsh&lt;/code&gt;. I installed &lt;code&gt;oh-my-zsh&lt;/code&gt; and I love it. I’m slowly discovering more about it. If you don’t use this as your shell, then search the web and set it up. I had the patience for it; therefore, so will you.&lt;/p&gt;
&lt;h2 id=&quot;enable-zmv&quot;&gt;Enable &lt;code&gt;zmv&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I first tried it from the command line.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ zmv
[Nope.]
$ autoload zmv
$ zmv
[Usage. Now I can use it!]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I added it to my &lt;code&gt;.zshenv&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# in $HOME/.zshenv
autoload zmv
alias zcp=&amp;#39;zmv -C&amp;#39;
alias zln=&amp;#39;zmv -L&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice! Now, for example, I can try this:&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ zmv -n &amp;#39;Page(*)/shot.jpg&amp;#39; &amp;#39;shot-${1}.jpg&amp;#39;
[Tell me which files you&amp;#39;d change, without changing them. Looks good!]
$ zmv &amp;#39;Page(*)/shot.jpg&amp;#39; &amp;#39;shot-${1}.jpg&amp;#39;
[Files magically change!]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I love it. You might, too. Enjoy.&lt;/p&gt;
</description>
        <pubDate>Thu, 23 Nov 2017 01:20:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/renaming-magically-with-zmv</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/renaming-magically-with-zmv</guid>
        
        
        <category>Microtechniques</category>
        
      </item>
    
      <item>
        <title>The Myth of Advanced TDD</title>
        <description>&lt;p&gt;“I want to get a lot of wisdom on TDD techniques”. Many people ask me about this, especially when they sign up for my mailing list. They want the “advanced stuff”. I have good news and bad news for them: I don’t believe in “advanced TDD”. If you want advanced testing techniques, then you’re probably looking for techniques that will make your code worse, not better. (I don’t want you to do that.) If you want “advanced TDD”, then you’ve probably missed the single most important bit of “wisdom on TDD techniques”: the tests are telling you how to improve your design, so listen!&lt;/p&gt;
&lt;h2 id=&quot;example-test-doubles-drive-abstraction&quot;&gt;Example: Test Doubles Drive Abstraction&lt;/h2&gt;
&lt;p&gt;For example, consider the case of our good friends, test doubles—also known as “mock objects”. In particular, what about &lt;em&gt;mocking&lt;/em&gt; method invocations—that means setting an expectation on a method invocation. Something like this:&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;describe &amp;quot;when receiving a barcode&amp;quot; do
  example &amp;quot;product found&amp;quot; do
    catalog = double(&amp;quot;a Catalog&amp;quot;, find_price: 795.cents)
    display = double(&amp;quot;a Display&amp;quot;)
    
    # This is a method expectation
    # Also known as &amp;quot;a mock&amp;quot;
    # We call this &amp;quot;mocking &amp;#39;display_price()&amp;#39;&amp;quot;
    # I also call this &amp;quot;setting an expectation on...&amp;quot;.
    display.should_receive(:display_price).with(795.cents)
    
    Sale.new(catalog, display).on_barcode &amp;quot;12345&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can read a lot of essays about test doubles, especially under the term &lt;em&gt;mock objects&lt;/em&gt;. Many people dislike them.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://images.jbrains.ca/mock_objects_suck_-_Google_Search.jpg&quot; alt=&quot;Do mock objects suck? Meh.&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Do mock objects suck? Meh.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I haven’t read all these articles, but I will bet you all the money in my wallet that 90% of them fall into two categories:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Ones that say “mock objects couple my tests too tightly to my design”.&lt;/li&gt;
&lt;li&gt;Ones that say “you don’t need mock objects if you replace side-effects with values (either input parameters or return values, depending on the situation)”.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;beyond-mock-objects&quot;&gt;Beyond Mock Objects&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;To the authors of the second group of articles&lt;/strong&gt; I say, “Yes, of course.” &lt;a href=&quot;/permalink/beyond-mock-objects&quot;&gt;I’ve written about this myself&lt;/a&gt;. Events and return values are the same thing. Many side-effects are events with a single, mandatory listener. You can replace side-effects with a value that represents the side-effect and then push the event listener up the call stack. Similarly, suppliers and values are the same thing. Many times we write code that depends on suppliers, when we have the opportunity to replace that with code that depends on the values it supplies. No stress. &lt;strong&gt;It doesn’t matter which design you choose if you see the equivalence between options.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Once I saw how to mechanically refactor between Supplier and Value as well as between Event and Return Value, I stopped worrying about choosing “the right design”, especially when it hadn’t yet become clear which design would fit the situation better. Now I just don’t worry about it. When it becomes clear that a Return Value fits better than an Event, I just refactor. This has the side-effect of replacing method expectations with checking value objects. Some people view this as simplifying the test; I view it as replacing one design with an equivalent one. &lt;strong&gt;Removing mock objects is not a goal; it’s an option.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;mock-objects-are-just-doing-their-job&quot;&gt;Mock Objects Are Just Doing Their Job&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;To the authors of the first group of articles&lt;/strong&gt; I say, “The test doubles are doing their job, so what’s the problem?” No, really. This “tight coupling” that the authors complain about amounts to overspecifying the behavior of the subject under test. So don’t do that. If your current design encourages you to overspecify behavior in order to write a test, then change the design. &lt;a href=&quot;/permalink/jmock-v-mockito-but-not-to-the-death&quot;&gt;I use test doubles as a design tool&lt;/a&gt; specifically because they put constant positive pressure on my design and they alert me to design risks as they happen!&lt;/p&gt;
&lt;p&gt;When you do &lt;a href=&quot;https://www.youtube.com/watch?v=jDwoBqPH0jk&quot;&gt;sit-ups&lt;/a&gt;, that usually causes pain. Notice the way that I worded that sentence: the act of doing sit-ups causes pain. Not the sit-ups themselves, but the combination of a few things: your technique, the amount of fat around your midsection, the surface on which you sit, and the act of performing the sit-up. Imagine instead that you tried to do some sit-ups, felt pain, and then concluded “sit-ups suck, because they cause pain”. Nonsense! Sometimes your technique needs work, but often sit-ups suck because you’re fat&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. The sit-ups are sending you a signal that you need to burn more fat. Sorry. Assuming that you care about how fat you are, &lt;strong&gt;the sit-ups are doing their job: signaling you to improve your body composition&lt;/strong&gt;. Sadly, sit-ups provide pretty harsh feedback, so I don’t recommend them as your primary way of getting feedback about your body composition. Not everyone needs to do sit-ups pain-free. You might find another way to get that feedback.&lt;/p&gt;
&lt;p&gt;When people say that mocking functions couples their tests too tightly to their production code, and then conclude that “mock objects suck”, &lt;strong&gt;they are blaming the sit-ups instead of their fat&lt;/strong&gt;. Don’t do this. The function expectations are trying to tell you something about your design, so listen!&lt;/p&gt;
&lt;p&gt;The example above doesn’t make this very clear. I like that test: it has a single action and a single assertion (the function expectation is an assertion). I can clearly discern the apparent objective of that test: if &lt;code&gt;Sale&lt;/code&gt; finds a price for the barcode, then it should try to display that price. Displaying the price is the objective of the test. Clean, clear, obvious.&lt;/p&gt;
&lt;h2 id=&quot;a-more-complicated-example&quot;&gt;A More Complicated Example&lt;/h2&gt;
&lt;p&gt;Now imagine that we’ve built the features “sell multiple items/introduce shopcart”, “update inventory”, and “compute sales taxes”. Now the test looks more like this:&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;describe &amp;quot;when receiving a barcode&amp;quot; do
  example &amp;quot;product found&amp;quot; do
    product_found = Product.new(price: 795.cents, taxes: [:HST_PE])
    catalog = double(&amp;quot;a Catalog&amp;quot;, :find_product =&amp;gt; product_found)
    
    display = double(&amp;quot;a Display&amp;quot;)
    shopcart = double(&amp;quot;a Shopcart&amp;quot;)
    inventory_gateway = double(&amp;quot;an Inventory Gateway&amp;quot;)

    display.should_receive(:display_price).with(product_found.price)
    shopcart.should_receive(:add_product).with(product_found)
    inventory_gateway.should_receive(:reserve_product).with(quantity: 1, product: product_found)
    
    Sale.new(catalog, shopcart, inventory_gateway, display).on_barcode &amp;quot;12345&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I like this test less: although it still has only one action, it now has three assertions. Moreover, if I want to check &lt;em&gt;only&lt;/em&gt; the inventory gateway behavior, I have to do something with the shopcart and display behaviors—either check them (who cares?) or shut them up (why force me to do this?). &lt;strong&gt;In similar situations, I see programmers blindly copy and paste these test doubles all over the place.&lt;/strong&gt; They don’t think they have a choice. They start writing articles that praise mock object libraries that act like Mockito (by making “lenient” the default choice). They say things like “I like spies more than mocks” (even though they are fundamentally the same things). Worse, they start writing articles about how mock objects “suck”. Sigh.&lt;/p&gt;
&lt;h2 id=&quot;what-if-we-listened-to-the-crying&quot;&gt;What If We Listened To the Crying?&lt;/h2&gt;
&lt;p&gt;The design is crying, and the tests are the cries. Instead of ignoring those cries, let’s listen to them. What do they say? First, &lt;strong&gt;irrelevant details in a test indicate involving modules that the test would rather ignore.&lt;/strong&gt; This means that we have an integrated test, even when it doesn’t look like we do. Injecting dependencies and using test doubles masks the problem, but doesn’t solve it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Duplicate assertions in a test indicate a missing abstraction.&lt;/strong&gt; Duplicate assertions? But the method expectations are all different. But are they? They have one thing in common: &lt;code&gt;product_found&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A function expectation in a test indicates the presence of side effect that we can often model as an event.&lt;/strong&gt; Morever, if we set an expectation on an action/verbal name (&lt;em&gt;display&lt;/em&gt; price, &lt;em&gt;add&lt;/em&gt; product, &lt;em&gt;reserve&lt;/em&gt; product), then we can replace those expectations with an event and it means the same thing. &lt;strong&gt;I can think of the event as an interface and the handler as an implementation of that interface&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;We can look at the patterns in the names to extract the event. Clearly, we should use the &lt;code&gt;Product&lt;/code&gt; as the event data, but what should we name the event? When should we display the price, add the product, or reserve the product in inventory? Why… when we have &lt;em&gt;found&lt;/em&gt; a product.&lt;/p&gt;
&lt;p&gt;How about &lt;code&gt;on_product_found(product)&lt;/code&gt; as the event? I like it!&lt;/p&gt;
&lt;p&gt;I can convert all three function expectations into handlers for the &lt;code&gt;product_found&lt;/code&gt; event. &lt;strong&gt;The test doubles have led me towards finding the missing abstraction.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;following-the-test-doubles-advice&quot;&gt;Following the Test Doubles’ Advice&lt;/h2&gt;
&lt;p&gt;Now the test becomes simpler, because I replace three similar interfaces with a single, equivalent one.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;describe &amp;quot;when receiving a barcode&amp;quot; do
  example &amp;quot;product found&amp;quot; do
    product_found = Product.new(price: 795.cents, taxes: [:HST_PE])
    catalog = double(&amp;quot;a Catalog&amp;quot;, :find_product =&amp;gt; product_found)

    event_listener = double(&amp;quot;an Event Listener&amp;quot;)

    event_listener.should_receive(:on_product_found).with(product_found)
    
    Sale.new(catalog, event_listener).on_barcode &amp;quot;12345&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to make this work as before, I introduce a &lt;code&gt;BroadcastEventListener&lt;/code&gt;, which broadcasts events to a collection of listeners; next I introduce event listeners for each of the three actions.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# In the entry point of the system...
sale = Sale.new(
  BroadcastEventListener.with_listeners(
    Display.new(), 
    Shopcart.new(), 
    InventoryGateway.connect(inventory_database)))
# ...install sale into the routing table to receive &amp;quot;scanned barcode&amp;quot; requests&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can easily implement the common interface on these classes.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;class Display
  def on_product_found(product)
    display_price(product.price)
  end
end

class Shopcart
  def on_product_found(product)
    add(product)
  end
end

class InventoryGateway
  # ...
  def on_product_found(product)
    reserve_product(quantity: 1, sku: product.sku)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If it worked better, then I could instead separate the event handlers from the model classes. I could even just register lambdas in the entry point.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# In the entry point of the system...
display = Display.new
shopcart = Shopcart.new  # why is this a singleton? Hm. Multiple shoppers?
inventory_gateway = InventoryGateway.connect(inventory_database)

sale = Sale.new(
  BroadcastEventListener.with_listeners(
    -&amp;gt; product { display.display_price(product.price) }
    -&amp;gt; product { shopcart.add(product) }
    -&amp;gt; product { inventory_gateway.reserve(quantity: 1, sku: product.sku) }))
# ...install sale into the routing table to receive &amp;quot;scanned barcode&amp;quot; requests&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;aside&quot;&gt;
Let’s ignore the comment about implementing &lt;code&gt;Shopcart&lt;/code&gt; as a singleton for now. I’ve put that in my inbox, so I’ll get to it later.
&lt;/p&gt;
&lt;p&gt;I consider these event listeners &lt;strong&gt;too simple to break&lt;/strong&gt;, but if you don’t, then you can easily introduce named classes for them and then check them separately. For example:&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;class ReserveItemForPurchaseAction &amp;lt; ProductFoundListener
  attr_reader :inventory_gateway
  
  def initialize(inventory_gateway)
    @inventory_gateway = inventory_gateway
  end
  
  def on_product_found(product)
    inventory_gateway.reserve(quantity: 1, sku: product.sku)
  end
end

describe &amp;quot;Reserve an item for purchase&amp;quot; do
  example &amp;quot;when a product is found&amp;quot; do
    inventory_gateway = double(&amp;quot;an Inventory Gateway&amp;quot;)
    
    inventory_gateway.should_receive(:reserve).with(quantity: 1, sku: sku)
    
    ReserveItemForPurchaseAction.new(inventory_gateway).on_product_found(Product.with(sku: sku))
  end   
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can’t think of any other tests for this, can you? Here I’ve simulated the case where the &lt;code&gt;InventoryGateway&lt;/code&gt; is some legacy service that requires clients to specify the number of items they’re reserving, even when we want to use the sensible default value of 1. If you want to check for a faulty event object, feel free, but I trust me. You don’t have to trust me nor you. I would design the other event listeners similarly.&lt;/p&gt;
&lt;p&gt;I can implement the &lt;code&gt;BroadcastEventListener&lt;/code&gt; to forward events without worrying about the event values themselves. This becomes generic behavior that we check once and then simply trust. To check the broadcaster, simply attach a few mock event listeners and check that all the listeners receive the same event that the broadcaster receives. If we decide to add some behavior to validate and canonicalize events, then we can add it somewhere near here.&lt;/p&gt;
&lt;h2 id=&quot;surveying-the-results&quot;&gt;Surveying the Results&lt;/h2&gt;
&lt;p&gt;In listening to the annoying function expectations in our tests, we did the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduced a high-level event, “on product found”, which makes the controller-level code so simple, it becomes almost self-evidently correct: if we find the product in the catalog, the signal the event “product found” with that product.&lt;/li&gt;
&lt;li&gt;Extracted a highly-reusable event broadcaster. When do we start the open-source project for code like it?&lt;/li&gt;
&lt;li&gt;Separated completely independent actions that previously just happened to reside in the same place. Adding an item to a shopper’s shopcart, displaying the price of that item, and reserving it for purchase in the inventory system don’t need to depend on each other to behave correctly, so why should we execute the others when we care about just one of them? We can decide later how to decorate these actions with error handling: should we warn about all the failures? should we fail if there are any failures? We can add this in the controller or we can introduce another specialized event listener.&lt;/li&gt;
&lt;li&gt;Highlighted the business rules in the controller: when a product is found, we notify the shopcart, the display, and the inventory gateway. If you don’t like this design, then defactor it to make the controller a closed facade. I wouldn’t feel tempted to test it with programmer tests, although I would probably check the end-to-end flow with Customer Tests—just not exhaustively. I would write only as many tests as the Customer needs to feel confident that we understood each other.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I consider this a significant win. When we add another feature that requires listening to the “product found” event, we will find that &lt;em&gt;really&lt;/em&gt; easily. Almost &lt;em&gt;disturbingly&lt;/em&gt; easy.&lt;/p&gt;
&lt;h2 id=&quot;advanced-tdd&quot;&gt;“Advanced TDD?”&lt;/h2&gt;
&lt;p&gt;So, would you consider this &lt;em&gt;advanced&lt;/em&gt; TDD? I don’t. I consider this &lt;em&gt;elementary&lt;/em&gt; TDD: &lt;strong&gt;feedback from the tests drives the design&lt;/strong&gt;. (Does anyone else remember when we went through the phase of calling it “test-driven design”?) The technique of TDD hasn’t changed; I’ve simply taken seriously the notion that &lt;strong&gt;if I notice problems in the tests, then they probably point to problems in the production code&lt;/strong&gt;. If you think of this as “advanced TDD”, then I suppose I would say that &lt;strong&gt;advanced TDD is little more than practising TDD more diligently&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You can do it, so why don’t you try?&lt;/p&gt;
&lt;h2 id=&quot;epilogue-eventsourcing&quot;&gt;Epilogue: Eventsourcing&lt;/h2&gt;
&lt;p&gt;Yes, yes. Eventsourcing blah blah blah. I get it. If I have techniques that nudge me towards extracting the events, then I feel good: even when I don’t use eventsourcing, I find the events anyway. Win-win.&lt;/p&gt;
&lt;h2 id=&quot;reactions&quot;&gt;Reactions&lt;/h2&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
A great article about how letting tests drive your design makes your code needlessly complicated and your tests less powerful. Don&apos;t think the author meant it that way, though. Also, he doesn&apos;t understand sit-ups. &lt;a href=&quot;https://t.co/X4gSxyTudm&quot;&gt;https://t.co/X4gSxyTudm&lt;/a&gt;
&lt;/p&gt;
— Tom Anderseine (&lt;span class=&quot;citation&quot; data-cites=&quot;tomwhoscontrary&quot;&gt;@tomwhoscontrary&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/tomwhoscontrary/status/931456510382825472?ref_src=twsrc%5Etfw&quot;&gt;November 17, 2017&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;I don’t include this to draw attention to any one person. On the contrary, I’ve heard this particular argument before. Tom elaborates:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Broadly, though, the area of code and number of places in the codebase you have to look to understand something (“what happens when we scan a barcode?”) has increased, and that makes it more complex.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have written about this elsewhere: &lt;a href=&quot;/permalink/modularity-details-pick-one&quot;&gt;“Modularity. Details. Pick One.”&lt;/a&gt;. In short, lack of modularity and obsession with details creates a positive feedback loop; introducing abstractions breaks the pattern. Well-named, well-designed abstractions make me more likely to &lt;em&gt;trust&lt;/em&gt; modules (classes) and therefore not &lt;em&gt;need&lt;/em&gt; to look at their details.&lt;/p&gt;
&lt;p&gt;In this way, I make systems out of simpler compositions of easier-to-combine pieces. I separate technology-oriented code from the business rules, so that the latter stand out more. I think I’ve achieved that here with the three listeners to the &lt;code&gt;product_found&lt;/code&gt; event, although we can argue about how exactly to write those three lines. In particular, I believe I’ve replaced one place to look for this behavior with… one place to look for this behavior! &lt;strong&gt;I don’t need to know &lt;em&gt;how&lt;/em&gt; those three listeners achieve their goals.&lt;/strong&gt; That reflects the trust earned by modularity and helpful names.&lt;/p&gt;
&lt;p&gt;People in the industry have been telling us this since the 1960s, even when they wrote about structured programming. Modularity has never gone out of style. The functional programming crowd is now beating this drum quite hard; we merely have more freedom in object-oriented designs and so need to constrain ourselves more to achieve modularity. The technique that I’ve outlined here shows one example of how I use tests to arrive at these abstractions so that I don’t have to “see” them up front.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/beyond-mock-objects&quot;&gt;“Beyond Mock Objects”&lt;/a&gt;. Don’t depend on a supplier when you have the opportunity to depend on the value that it supplies.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/jmock-v-mockito-but-not-to-the-death&quot;&gt;“JMock v. Mockito, But Not To the Death”&lt;/a&gt;. JMock helps me avoid accidental complication in my design by nagging me; Mockito avoids nagging me while I remove accidental complication from legacy code.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/modularity-details-pick-one&quot;&gt;“Modularity. Details. Pick One.”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/abstraction-the-goal-of-modular-design&quot;&gt;“Abstraction: The Goal of Modular Design”&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;No, I’m not body shaming anyone. I used to be over 70 kg overweight. “Being fat” is just a fact of life for some people. I don’t use it as a criticism. I was fat. I’m now much, much less fat. If you want proof, find any video or photo of me from 2011 or earlier.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 16 Nov 2017 05:25:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-myth-of-advanced-tdd</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-myth-of-advanced-tdd</guid>
        
        
        <category>Simple Design</category>
        
        <category>Test Doubles</category>
        
      </item>
    
      <item>
        <title>Guard Rails, Not Prison Bars</title>
        <description>&lt;p&gt;A recent experience with a hotel coffee machine illustrated one primary difference of philosophy related to software design. It’s a Keurig machine and my wife Sarah was figuring out how to use it to make coffee. She noticed that when she inserted a K-Cup (the little containers of coffee), then the lid for the water reservoir popped open, so that she could fill it with water. At first, that seemed helpful, but immediately, I wondered about being able to open that reservoir even without inserting a K-Cup. As far as we can tell, it can’t be done. Not only that, but since Sarah needed to walk across the hotel room in order to fetch water from the bathroom sink, by the time she returned to the coffee machine to finish the &lt;em&gt;approved Keurig machine workflow&lt;/em&gt;, the machine did nothing. She immediately told me that she couldn’t tell the difference between the machine heating up slowly and doing nothing. What had she done incorrectly? We presumed that she had taken “too long” (Why should this matter? Why is there a time limit on making a cup of coffee?) and that the machine needed to start the &lt;em&gt;approved Keurig machine workflow&lt;/em&gt; again. This meant turning the machine on (Why?), opening and closing the K-Cup compartment &lt;em&gt;only in order to then&lt;/em&gt; close the water reservoir lid &lt;em&gt;only in order to then&lt;/em&gt; push the “brew” button. From what I can tell, for no good reason, we needed to run the &lt;em&gt;approved Keurig machine workflow&lt;/em&gt; twice in order to compensate for some design element (the machine “timed out”, we guess) that seems to me entirely irrelevant to the task of brewing coffee.&lt;/p&gt;
&lt;p&gt;And I immediately thought of programmers making in-house workflow frameworks or multi-step UI wizards for their enterprise. And I sighed.&lt;/p&gt;
&lt;h2 id=&quot;give-me-guard-rails-not-prison-bars&quot;&gt;Give Me Guard Rails, Not Prison Bars&lt;/h2&gt;
&lt;p&gt;When you design a workflow of any kind, please design the workflow as guard rails–protective guidelines for how to compose the individual steps into a useful way–instead of as prison bars–locking the individual steps into place either through data hiding or, worse, through tangled dependencies on shared memory. If you design the workflow as guard rails, then I get the best of both worlds: automatic protection against making a mistake when putting the steps together, but the freedom to execute and evaluate (test! check!) the individual steps without being forced to execute them in the workflow. &lt;em&gt;This last difference matters most to me.&lt;/em&gt; When you give me prison bars, you force me to run the workflow in order to check the steps. This leads me towards integrated tests, which we know &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;are a scam&lt;/a&gt;. When you instead give me guard rails, you let me execute the individual steps outside the workflow, which gives me two benefits: the ability to learn how the steps work without dragging the entire workflow into the exercise &lt;em&gt;and&lt;/em&gt; the option to use the steps to solve other problems outside the originally-intended workflow. &lt;em&gt;You&lt;/em&gt;, the programmer designing the original workflow, can take advantage of both these benefits! Imagine if you find out that clients are using your steps in novel ways, then that might give you ideas for new features to sell to your market. Moreover, not having to run all your tests through the workflow makes it cheaper to gain more confidence in the correctness of the steps.&lt;/p&gt;
&lt;p&gt;Finally–and I know I’m late to the party on this–focusing more on the correctness of the steps and less on the overall workflow might nudge you in the direction of using really simple mechanisms to collect steps into workflows, such as the dependable “compose functions” operation that lies at the heart of functional programming. You don’t need to program in Haskell to build dependable function pipelines: you can do it with methods in Java, too. Many of your “workflows” can easily be turned into method pipelines, and once the steps seem solid, the simplest workflows become &lt;a href=&quot;#references&quot;&gt;Too Simple to Break&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-keurig-without-prison-bars&quot;&gt;The Keurig Without Prison Bars&lt;/h2&gt;
&lt;p&gt;Returning to our ersatz-coffee machine, I asked Sarah whether there was any way to open the water reservoir without closing the K-Cup compartment. She found none. We could remove the prison bars by adding a little button to pop open the water reservoir, while still making it possible for closing the K-Cup compartment to have the same effect. (I’m no engineer, but I don’t think I’m significantly underestimating the effort involved in designing the machine to do this.)&lt;/p&gt;
&lt;p&gt;If I’ve put a K-Cup in the compartment, then waited “too long” (Why?!?) to pour water in the back, I don’t want to have to re-open the K-Cup compartment just to convince the machine that it’s safe to pour in water! I’ve worked with similar machines where, when you try to open to the coffee-pod compartment, it assumes that you’ve just brewed coffee, and so it disposes of the unused coffee pod! Why should I waste any energy on figuring this out?! Just let me pour water whenever I think I need it without being forced to understand how the rest of the workflow works!&lt;/p&gt;
&lt;p&gt;If you force me to use the machine only to brew coffee, then you force the hotel to provide a kettle for boiling water separately for other drinks. If you take away the prison bars, then I can use the same machine to dispense hot water, which I can use on those nights when I need to drink some powdered cold-symptom drugs in order to have enough relief from nasal congestion to fall asleep. Remove the prison bars and you get this extra behavior &lt;em&gt;free&lt;/em&gt;. Keep the prison bars in place and either I need to duplicate the equipment or, more likely, the hotel simply makes it impossible for me to get to sleep. Sleeping is, you should know, the primary benefit I want from a hotel room.&lt;/p&gt;
&lt;h2 id=&quot;the-best-of-both-worlds&quot;&gt;The Best Of Both Worlds&lt;/h2&gt;
&lt;p&gt;I recommend designing software elements so that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We can execute them individually, so that we can check them thoroughly and rearrange them into useful systems.&lt;/li&gt;
&lt;li&gt;We see a clear way to put them together into standard workflows, either using Template Method or by designing the steps to assemble into an obvious pipeline (the output each of function becomes the input to the next).&lt;/li&gt;
&lt;li&gt;The elements depend less on their context, so that for example we don’t assume that they all &lt;em&gt;must&lt;/em&gt; talk to the same shared data source, even if that’s how we &lt;em&gt;expect&lt;/em&gt; to use them for now. (Some day someone will read about CQRS and want to split queries and commands into different data sources. Guaranteed.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This way, you get the best of both worlds: we know how to assemble the elements into the workflows we need now without restricting how we might adapt them to future uses. If it seems to you that the elements will be difficult to use unless they are put together in the exact workflow that you have in mind, then I encourage you to interpret that as a sign that they depend too much on their collective context. In this case, apply the &lt;a href=&quot;https://dependency-inversion-principle.jbrains.ca&quot;&gt;Dependency Inversion Principle&lt;/a&gt; to improve the situation. I also encourage you to try to design the elements to be easily composed, in order to take pressure off checking the workflow. Also remember that, if you want to check the workflow, then you can always stub the steps that you’re not checking and set method expectations on the step you’re checking. This way, you can write a test like “if step 2 raises error X, then we don’t run step 3, but instead skip to step 4” without worrying about any of the details of what steps 2, 3, and 4 otherwise do. This makes even the workflows potentially reusable!&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://junit.org/junit4/faq.html#best_3&quot;&gt;“Too Simple to Break”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://dependency-inversion-principle.jbrains.ca&quot;&gt;Articles on the Dependency Inversion Principle&lt;/a&gt;. A series of articles describing the principle and its consequences.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/how-reuse-happens&quot;&gt;“How Reuse Happens”&lt;/a&gt;. “If you want reuse, you have to make it happen.” I describe an example of how following some basic low-level design principles helps lead me towards more reusable code. Reuse is not a fantasy, but it requires effort.&lt;/p&gt;
</description>
        <pubDate>Fri, 18 Aug 2017 13:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/guard-rails-not-prison-bars</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/guard-rails-not-prison-bars</guid>
        
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Getting Started with Contract Tests</title>
        <description>&lt;p&gt;Today’s article answers a question that I received recently.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey, I attended a talk of yours about continuous delivery. One of the main takeaways from that was the mention of Contract Testing. In my team we’re thinking about trying it out, starting first with one of our features and testing the contract Frontend&amp;lt;-&amp;gt;Backend. We’ve seen some tools that might help like Pact, but are not sure if that’s the right way to go. If you could give us any help, it would be highly appreciated.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, don’t look for tools. More important, for now, is to document each module’s expectations of its collaborators. I prefer to document them as running examples, meaning tests. For example, if a controller expects a model’s update function to throw an exception in case it can’t find the entity to update, then write a test for the model interface like this:&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# Something like RSpec/Ruby

describe “no entity exists matching the ID” do
  model = model_without(entity) # maybe stub the storage not to find the entity by its ID

  expect(() -&amp;gt; { model.update(entity) }).to_raise(EntityNotFoundException) # entity is a snapshot of the state that you want to save
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, you have deferred the implementation of &lt;code&gt;model_without(entity)&lt;/code&gt; to implementations of the &lt;code&gt;Model&lt;/code&gt; interface/protocol.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;Of course, you don’t literally have an interface/protocol called &lt;code&gt;Model&lt;/code&gt; nor a class called &lt;code&gt;Controller&lt;/code&gt;. These are placeholders.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Whoever implements &lt;code&gt;Model&lt;/code&gt; has to provide a way to initialize a &lt;code&gt;Model&lt;/code&gt; instance that can’t find/doesn’t have &lt;code&gt;entity&lt;/code&gt;. An in-memory version could just delete it from its internal collection. A database version would do &lt;code&gt;delete from customers where customer_id = ?&lt;/code&gt;. The Contract Test doesn’t care about this detail—it describes behavior that clients rely on without referring to a specific implementation of the collaborator.&lt;/p&gt;
&lt;p&gt;It’s quite common, in fact, to start with a concrete test for the production implementation of the collaborator, and then extract a Contract Test by extracting a factory function for creating the subject of the test.&lt;/p&gt;
&lt;h2 id=&quot;a-simple-example-in-java&quot;&gt;A Simple Example in Java&lt;/h2&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public class FindPriceInMemoryCatalog {
  @Test
  public void productFound() throws Exception {
    InMemoryCatalog catalog = new InMemoryCatalog(Collections.singletonMap(&amp;quot;::barcode::&amp;quot;, &amp;quot;::price::&amp;quot;));
    assertEquals(&amp;quot;::price::&amp;quot;, catalog.findPrice(&amp;quot;::barcode&amp;quot;));
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public abstract class FindPriceInCatalogContract {
  @Test
  public void productFound() throws Exception {
    Catalog catalog = catalogWith(&amp;quot;::barcode::&amp;quot;, &amp;quot;::price::&amp;quot;);
    assertEquals(&amp;quot;::price::&amp;quot;, catalog.findPrice(&amp;quot;::barcode&amp;quot;));
  }

  public abstract Catalog catalogWith(String barcode, String matchingPrice);
}

public class FindPriceInMemoryCatalog extends FindPriceInCatalogContract {
  public Catalog catalogWith(String barcode, String matchingPrice) {
    return new InMemoryCatalog(Collections.singletonMap(barcode, matchingPrice))
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;semantics-and-syntax&quot;&gt;Semantics and Syntax&lt;/h2&gt;
&lt;p&gt;These tests check the &lt;em&gt;semantics&lt;/em&gt; of the contract—the meaning. They check that implementations of &lt;code&gt;Model&lt;/code&gt; behave the way that clients of &lt;code&gt;Model&lt;/code&gt; expect them to. They check &lt;em&gt;behavior&lt;/em&gt;. Tools like Pact (and Bogus and Chado and whatever else is out there) only check the &lt;em&gt;syntax&lt;/em&gt; of the contract—the shape. They check that implementations of &lt;code&gt;Model&lt;/code&gt; have the method signatures that clients expect. In languages with compile-time type checkers (Java, C#, Haskell, C++), the compiler runs these tests for you. Checking the syntax tells you that the pieces will fit together, but that’s often less than half the story. Check the semantics tells you that the pieces will &lt;em&gt;work&lt;/em&gt; together. As far as I know, Pact doesn’t help with that.&lt;/p&gt;
&lt;h2 id=&quot;step-away-from-the-tools&quot;&gt;Step Away From the Tools&lt;/h2&gt;
&lt;p&gt;I would recommend that you just start writing Contract Tests as best you can. Follow these simple rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If Client &lt;code&gt;A&lt;/code&gt; stubs &lt;code&gt;B.foo()&lt;/code&gt; to return value &lt;code&gt;X&lt;/code&gt;, then write a Contract Test for &lt;code&gt;B&lt;/code&gt; that shows when to &lt;code&gt;expect(foo()).toEqual(X)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If Client &lt;code&gt;A&lt;/code&gt; expects (should receive) &lt;code&gt;B.foo(a, b, c)&lt;/code&gt;, then write a Contract Test for &lt;code&gt;B&lt;/code&gt; that runs &lt;code&gt;foo(a, b, c)&lt;/code&gt; (as the action of the test) and documents the result.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, if &lt;code&gt;A&lt;/code&gt; assumes that &lt;code&gt;B.foo()&lt;/code&gt; can return &lt;code&gt;X&lt;/code&gt; (or raise error &lt;code&gt;Y&lt;/code&gt;), then you need a test for &lt;code&gt;B&lt;/code&gt; that shows &lt;em&gt;when this happens&lt;/em&gt;; and if &lt;code&gt;A&lt;/code&gt; needs to invoke &lt;code&gt;B.foo(a, b, c)&lt;/code&gt;, then you need a test for &lt;code&gt;B&lt;/code&gt; that shows that it responds to &lt;code&gt;foo(a, b, c)&lt;/code&gt;. Pact might help you with the second kind of test, but I recommend writing those tests yourself for a while, before looking for a tool to streamline that for you.&lt;/p&gt;
</description>
        <pubDate>Sun, 25 Jun 2017 14:03:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/getting-started-with-contract-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/getting-started-with-contract-tests</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
        <category>Test Doubles</category>
        
      </item>
    
      <item>
        <title>When Subclasses Are Ready To Die</title>
        <description>&lt;p&gt;I don’t like to inherit implementation (create subclasses).&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; When refactoring class hierarchies, I often pull behavior up into superclasses, then out into collaborators.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; Over time, I might find myself left with subclasses that only differ by overriding methods to return different constant values. Smalltalkers are used to this, but I never felt entirely comfortable with it. (No, I can’t explain that.) I often end up here because I’ve moved all the significant behavior variations out into collaborating objects, leaving behind tiny differences. The resulting subclasses amount to nothing more than slightly-varied configurations of a common type. We might end up with a situation with the same shape as this stupid, trivial example.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;class Vehicle {
  // much greatness, then
  abstract int countWheels();
}

class Bicycle extends Vehicle {
  int countWheels() { return 2; }
}

class Trikke extends Vehicle {
  int countWheels() { return 3; }
}

class OrdinaryAutomobile extends Vehicle {
  int countWheels() { return 4; }
}

class HeavyDutyTruck extends Vehicle {
  HeavyDutyTruck(int axles) {
    this.axles = axles;
  }
  
  // I don&amp;#39;t actually know anything about vehicles.
  int countWheels() { return someFunctionOf(this.axles); }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In most situations it becomes clear to us that this proliferation of subclasses becomes a burden. I might notice this when I have trouble finding a significant, valuable, &lt;em&gt;meaningful&lt;/em&gt; name for a minor variation of &lt;code&gt;Vehicle&lt;/code&gt;. I think “I just want to create this thing and I don’t care what it’s called!”&lt;/p&gt;
&lt;p&gt;Of course, in Java, I can use an anonymous subclass, but not all languages offer this option (C#—at least the last time I looked). Anonymous objects make me nervous, anyway, because programmers have a habit of adding behavior to them without giving them names, forcing extra work on us to reverse-engineer the meaning of the behavior. Even ignoring these point, we don’t need subclasses for such minor differences, since they don’t change &lt;em&gt;implementation&lt;/em&gt; at all, but merely change values. In this situation, we can replace the subclasses with a Factory and make &lt;code&gt;numberOfWheels&lt;/code&gt; a read-only property of &lt;code&gt;Vehicle&lt;/code&gt; whose value we can set in its constructor.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;class Vehicle {
  Vehicle(/* ...stuff... */, int numberOfWheels) {
    // greatness, then
    this.numberOfWheels = numberOfWheels;
  }
  
  // much greatness, then
  int countWheels() { return this.numberOfWheels; }
}

// You don&amp;#39;t have to call this VehicleFactory!
class Vehicles {
  static Vehicle bicycle() { 
    return new Vehicle(/* blah */, 2);
  }

  static Vehicle trikke() { 
    return new Vehicle(/* blah */, 3);
  }
  
  // and so on...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If it turns out that &lt;code&gt;HeavyDutyTruck&lt;/code&gt; has some significant behavior variations, then the Factory can return a &lt;code&gt;HeavyDutyTruck&lt;/code&gt; to the invoker, even though the invoker doesn’t care. Indeed, this is what makes a Factory a Factory.&lt;/p&gt;
&lt;p&gt;From this experience, I gleaned a lesson.&lt;/p&gt;
&lt;section class=&quot;highlight&quot;&gt;
&lt;p&gt;When subclasses differ only in methods that return values, consider removing the subclasses my moving the values into the superclass’s constructor.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&quot;not-just-values&quot;&gt;Not Just Values!&lt;/h2&gt;
&lt;p&gt;Today I read &lt;a href=&quot;https://two-wrongs.com/dynamic-dispatch-in-haskell-how-to-make-code-extendable&quot;&gt;“Dynamic Dispatch in Haskell, or: How Can I Make My Code Extendable?”&lt;/a&gt;, which led me to the Stack Overflow discussion &lt;a href=&quot;https://stackoverflow.com/questions/13106683/dynamic-dispatch-in-haskell&quot;&gt;“Dynamic dispatch in Haskell”&lt;/a&gt;, which led me to a minor aha! moment.&lt;/p&gt;
&lt;section class=&quot;highlight&quot;&gt;
&lt;p&gt;With functional programming style, functions are values, and so we can apply this same refactoring to eliminate or avoid heavyweight designs involving Typeclasses. We can treat even significant behavior variations—implemented as functions—the same way we treat minor variations in values. We can do this because functions are also values!&lt;/p&gt;
&lt;/section&gt;
&lt;p&gt;This immediately triggered me to recall the wonderful &lt;a href=&quot;https://www.harukizaemon.com/blog/2010/03/01/functional-programming-in-object-oriented-languages/&quot;&gt;“Functional programming in object oriented languages”&lt;/a&gt; in which Simon observes that “An object is a collection of partially applied functions”… and a few little things clicked into place. This should make my occasional foray into functional programming significantly less scary: when I think I want Typeclasses—especially since I don’t really understand Typeclasses yet—I have a trick to talk myself out of it.&lt;/p&gt;
&lt;p&gt;Here we have another idea that eluded me… and then suddenly became obvious. It feels jarring, but I like it.&lt;/p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Chris in Stockholm (aka ~kqr), &lt;a href=&quot;https://two-wrongs.com/dynamic-dispatch-in-haskell-how-to-make-code-extendable&quot;&gt;“Dynamic Dispatch in Haskell, or: How Can I Make My Code Extendable?”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stack Overflow, &lt;a href=&quot;https://stackoverflow.com/questions/13106683/dynamic-dispatch-in-haskell&quot;&gt;“Dynamic dispatch in Haskell”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Simon Harris, &lt;a href=&quot;https://www.harukizaemon.com/blog/2010/03/01/functional-programming-in-object-oriented-languages/&quot;&gt;“Functional programming in object oriented languages”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Erich Gamma and others. &lt;a href=&quot;https://link.jbrains.ca/11ATEqK&quot;&gt;&lt;em&gt;Design Patterns&lt;/em&gt;&lt;/a&gt;. Don’t just look at the class diagrams! Pay special attention to the &lt;em&gt;alternatives and drawbacks&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/series#improving-names&quot;&gt;“Improving Names”&lt;/a&gt;. A series of articles on how to improve names and the benefits this conveys to our designs.&lt;/p&gt;
&lt;p&gt;John Backus, &lt;a href=&quot;https://www.csc.villanova.edu/~beck/csc8310/BackusFP.pdf&quot;&gt;“Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs”&lt;/a&gt;. &lt;em&gt;Conventional programming languages are growing ever more enormous, but not stronger. Inherent defects at the most basic level cause them to be both fat and weak […]&lt;/em&gt; This was 1978. It has got both better and worse, from what I can tell.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I find it too easy to violate the supertype’s contract. I see too many examples of programmers tangling superclass and subclass together. It creates a mess that distracts too much from getting things done. The risk seems lower with interfaces/protocols.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;See the classic Refactoring called “Replace Inheritance with Delegation”, one of the centerpiece refactorings in rescuing legacy code. (&lt;a href=&quot;https://www.jetbrains.com/help/idea/2017.1/replace-inheritance-with-delegation.html&quot;&gt;IDEA 2017.1 supports this refactoring directly!&lt;/a&gt;)&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Wed, 10 May 2017 14:22:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/when-subclasses-are-ready-to-die</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/when-subclasses-are-ready-to-die</guid>
        
        
        <category>Simple Design</category>
        
      </item>
    
      <item>
        <title>Taking a Pragmatic View of Isolated Tests</title>
        <description>&lt;p&gt;I’ve been teaching programmers about the value of isolated tests&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; for a long time, and recently I’ve seen increasing resistance to the idea. I worry that this comes partly from having presented motivations and reasons that tends towards the overly-abstract, ironically enough. Perhaps I can improve matters by returning to the concrete issues and constraints that led me to being exploring this idea in the first place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consider the following questions&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When I want to fix a problem within the system’s domain or business logic, why should the system distract me with infrastructure or technology issues?&lt;/li&gt;
&lt;li&gt;When I see a problem with a web page template, why should I have to worry about how to grab data from the database to display on that page?&lt;/li&gt;
&lt;li&gt;When I see a problem with a web page template, why should I have to worry about the username I use to log in? or the workflow that leads to that page?&lt;/li&gt;
&lt;li&gt;When I see data not making it into a database correctly, why should it block me to have a configuration problem with the web server?&lt;/li&gt;
&lt;li&gt;When a framework service, like parsing request data, behaves differently than I expect it to, why should I have to know the details of the domain of the application in order to feel confient that I know how to integrate the service?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;We could think of more if we spent another 15 minutes together, but I think this suffices.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;All these questions have a common element: the corresponding distractions reflect excessive coupling and/or insufficient cohesion. They show a violation of the &lt;a href=&quot;https://blog.thecodewhisperer.com/series#dependency-inversion-principle-dip&quot;&gt;Dependency Inversion Principle&lt;/a&gt;. The resulting (integrated) tests cost more than they generate value. If we try to test these systems after the fact, then in the moment we stick to manual, integrated tests, because of expediency. If we use integrated tests to drive building these systems, then in the moment we put everything in one place, because of expediency. We risk taking well-designed systems for granted, so perhaps we too easily forget the value of test-driving with isolated tests, which nag us continually to respect the &lt;a href=&quot;https://blog.thecodewhisperer.com/series#dependency-inversion-principle-dip&quot;&gt;DIP&lt;/a&gt;. &lt;em&gt;When you put it this way, I find it hard to argue against!&lt;/em&gt; This leads me to wonder what has gone wrong with “how I’ve put it” up to now.&lt;/p&gt;
&lt;p&gt;I suspect that, by the time I sat down to write my past articles on this topic, I’d spent so much time thinking about the common elements that I’d abstracted them away too much. When I discuss these issues on podcasts, I try hard to help everyone relate to the problems, and so I don’t talk enough about the concrete, specific situations that led me to reach the conclusions I’ve reached about the dangers of integrated tests and the value of isolated tests. I either assume that the audience knows &lt;em&gt;or&lt;/em&gt; I don’t want to anchor people in the audience to a particular situation &lt;em&gt;or&lt;/em&gt; I simply repeat a seemingly-obvious abstraction &lt;em&gt;out of expediency&lt;/em&gt;. I’m sorry about that.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
I use isolated tests to drive improvements in my designs. They help me find distracting violations of the &lt;a href=&quot;https://blog.thecodewhisperer.com/series#dependency-inversion-principle-dip&quot;&gt;DIP&lt;/a&gt; in existing code and they help me avoid violating the &lt;a href=&quot;https://blog.thecodewhisperer.com/series#dependency-inversion-principle-dip&quot;&gt;DIP&lt;/a&gt; in new code. Respecting the &lt;a href=&quot;https://blog.thecodewhisperer.com/series#dependency-inversion-principle-dip&quot;&gt;DIP&lt;/a&gt; often looks like overkill in the moment and I almost always deeply regret violating the &lt;a href=&quot;https://blog.thecodewhisperer.com/series#dependency-inversion-principle-dip&quot;&gt;DIP&lt;/a&gt; in retrospect.
&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;By &lt;em&gt;isolated tests&lt;/em&gt; here I mean the opposite of &lt;em&gt;integrated tests&lt;/em&gt;; I’m not referring to tests that execute in isolation from the other tests. (I take that sense of isolation for granted and forget even to mention it at all.) You might have seen similar terms like &lt;em&gt;solitary&lt;/em&gt; or &lt;em&gt;focused&lt;/em&gt;. I mean a microtest that checks one small part of the system in isolation from its “complicated” production dependencies.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Fri, 17 Mar 2017 15:38:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/taking-a-pragmatic-view-of-isolated-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/taking-a-pragmatic-view-of-isolated-tests</guid>
        
        
        <category>Simple Design</category>
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
        <category>Test Doubles</category>
        
        <category>Surviving Legacy Code</category>
        
      </item>
    
      <item>
        <title>Deploying Jekyll to Heroku using GitLab CI</title>
        <description>&lt;aside&gt;
&lt;p&gt;Following is not only a tutorial, but also an example of the notes that I take when I figure out how to do something. In here you’ll find &lt;em&gt;Learning Tests&lt;/em&gt; — at least the fully-documented, incremental learning spirit of them — in enough detail to recreate the learning artifacts months (years, even) from now, if you need to re-learn the steps from the beginning.&lt;/p&gt;
&lt;/aside&gt;
&lt;!-- more --&gt;
&lt;p&gt;I would like to use GitLab CI in order to be able to separate rebuilding a Jekyll site from deploying the static web pages to a production web server. I know that I &lt;em&gt;can&lt;/em&gt; deploy a Jekyll project to Heroku using a buildpack to build the static site remotely; however, that seems wasteful to me compared to merely deploying the resulting static site into production. Since I don’t know how to use GitLab CI, I’d like to explore what it does. I most definitely &lt;em&gt;do not&lt;/em&gt; want to use my Jekyll project to learn the basics, since this adds moving parts that I don’t thoroughly understand. Instead, I’d rather do something closer to writing learning tests, in order to limit the unknowns.&lt;/p&gt;
&lt;h2 id=&quot;readme&quot;&gt;README&lt;/h2&gt;
&lt;p&gt;I’m following the instructions at &lt;a href=&quot;https://docs.gitlab.com/ce/ci/quick_start/README.html&quot; class=&quot;uri&quot;&gt;https://docs.gitlab.com/ce/ci/quick_start/README.html&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; to the root of the project. This file includes the instructions for GitLab to run. I assume that this works like a Git &lt;code&gt;post-receive&lt;/code&gt; hook.&lt;/li&gt;
&lt;li&gt;Configure a GitLab Runner, which seems to require Go (according to what I’ve read), which makes me nervous, because I don’t want to adopt too many dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I want the GitLab CI configuration file to do the equivalent of saying “Hello, world”, so that I can simply verify that it runs. I also want to use a dead-simple project with nothing special in it, so that I can poke around, run manual tests, without fear of injuring anything significant.&lt;/p&gt;
&lt;p&gt;So, I did the following:&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $WORKSPACES_ROOT # Where I put projects on my file system
$ git init learn-gitlab-ci&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a new project, initializing a Git repository inside it. Next, I go to &lt;a href=&quot;https://gitlab.com&quot; class=&quot;uri&quot;&gt;https://gitlab.com&lt;/a&gt; to create a repository there for this project, so that I can push to it. In my case, I ended up with a remote repository at &lt;code&gt;git@gitlab.com:jbrains/learn-gitlab-ci.git&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ export PROJECT_ROOT=&amp;quot;$WORKSPACES_ROOT/learn-gitlab-ci&amp;quot;
$ cd $PROJECT_ROOT
$ git remote add gitlab git@gitlab.com:jbrains/learn-gitlab-ci.git
$ git remote -v
gitlab  git@gitlab.com:jbrains/learn-gitlab-ci.git (fetch)
gitlab  git@gitlab.com:jbrains/learn-gitlab-ci.git (push)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I’m ready to add content to this project, so I start with the GitLab CI configuration file.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT
$ mvim .gitlab-ci.yml&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# The new content of .gitlab-ci.yml
before_script:
  - echo &amp;quot;This runs before the build jobs.&amp;quot;

build_job_1:
  - echo &amp;quot;This is the first build job.&amp;quot;

build_job_2:
  - echo &amp;quot;This is the second build job.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives me something to commit, push, and wonder where in the universe &lt;code&gt;echo&lt;/code&gt; echoes text to.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT
$ git add -A
$ git commit -m &amp;quot;Trying to detect the basic GitLab CI job lifecycle.&amp;quot;
$ git push gitlab master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After pushing these changes to GitLab, I go to the GitLab project at &lt;a href=&quot;https://gitlab.com&quot; class=&quot;uri&quot;&gt;https://gitlab.com&lt;/a&gt; to find the &lt;em&gt;Pipelines&lt;/em&gt; page for the project. Conveniently, I find the &lt;em&gt;Pipelines&lt;/em&gt; page at &lt;a href=&quot;https://gitlab.com/jbrains/learn-gitlab-ci/pipelines&quot; class=&quot;uri&quot;&gt;https://gitlab.com/jbrains/learn-gitlab-ci/pipelines&lt;/a&gt;. Before I get there, I find out by email that my pipeline has failed.&lt;/p&gt;
&lt;p&gt;On the pipelines page, I see a message showing that the pipeline has failed for the reason “yaml invalid”. Weird, because the YAML syntax looked correct to me. Conveniently, at the &lt;em&gt;Pipelines&lt;/em&gt; page, I see a button labeled “CI Lint”, which, if I press, should give me some useful feedback about the syntax of my GitLab CI configuration file… so I press it.&lt;/p&gt;
&lt;p&gt;Curiously, when I press “CI Lint”, I end up at a page which threatens to let me edit my GitLab CI configuration file, except that the editor has no content, which makes me wonder whether, somehow, I failed to put the file in the right place. Perhaps it has the wrong name? Perhaps something else weird has gone wrong? I don’t get it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is one of the many reasons that I decided not to try this with my Jekyll project. At least now, I don’t feel tempted to become distracted by wondering if Jekyll somehow relates to the problem.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Strange. The file &lt;code&gt;$PROJECT_ROOT/.gitlab-ci.yml&lt;/code&gt; appears in the &lt;em&gt;Files&lt;/em&gt; section of my GitLab repository. It has the content that I expect. That content looks like valid YAML. I have no idea how this could fail.&lt;/p&gt;
&lt;p&gt;OK. Maybe I need to paste the GitLab CI configuration YAML into this text editor in order to check it. I try that. Sure enough, when I press “validate”, I see the same error message: &lt;em&gt;jobs:build_job_1 config should be a hash&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Aha! Looking more closely, I misread the sample GitLab CI configuration file. The build jobs need to be a hash, and I’ve made them a list. I try to fix the build job accordingly.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# .gitlab-ci.yml
before_script:
  - echo &amp;quot;This runs before the build jobs.&amp;quot;

build_job_1:
  script:
    - echo &amp;quot;This is the first build job.&amp;quot;

build_job_2:
  script:
    - echo &amp;quot;This is the second build job.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test this, I need to commit, then push.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT
$ git add -A
$ git commit -m &amp;quot;The GitLab CI configuration file now specific build job scripts correctly, as far as I can tell.&amp;quot;
$ git push gitlab master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I browse to the GitLab project’s &lt;em&gt;Pipelines&lt;/em&gt; page again and see success! Well… success &lt;em&gt;so far&lt;/em&gt;. The two build jobs &lt;code&gt;build_job_1&lt;/code&gt; and &lt;code&gt;build_job_2&lt;/code&gt; are &lt;em&gt;running&lt;/em&gt;, which surprises me a little, since I made them very, very short jobs.&lt;/p&gt;
&lt;p&gt;No matter. While I’m waiting for the jobs to complete, I go back to the “CI Lint” page, paste the new contents of the GitLab CI configuration file, then validate the file. Looking at the output, I learn the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The syntax is correct.&lt;/li&gt;
&lt;li&gt;I can expect the &lt;code&gt;before_script&lt;/code&gt; to run before &lt;em&gt;each build job&lt;/em&gt;, much like &lt;code&gt;@Before&lt;/code&gt; in JUnit. I should therefore make sure that &lt;code&gt;before_script&lt;/code&gt; does something idempotent.&lt;/li&gt;
&lt;li&gt;I can specify &lt;code&gt;on_success&lt;/code&gt; for each build job, which &lt;em&gt;I presume&lt;/em&gt; runs some commands when the build job succeeds. This gives me something to look up so that I learn more details about the contract with GitLab CI.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While I learned these things, my build jobs finished. They took over two minutes to run, they succeeded, and when I click on each job, I see both the source commands (the &lt;code&gt;echo&lt;/code&gt; command) and the output (the echoed text itself). This makes me feel very good about exploring the build job and pipeline lifecycle in more detail.&lt;/p&gt;
&lt;p&gt;I also notice in the output that GitLab CI is using &lt;code&gt;docker&lt;/code&gt; with Ruby image 2.1. &lt;em&gt;Can I choose the Ruby version that GitLab CI uses to run our build jobs?&lt;/em&gt; I’ll have to look that up. This also gives me hope that we don’t need to install &lt;code&gt;docker&lt;/code&gt; and &lt;code&gt;go&lt;/code&gt; and all that nonsense, because GitLab does that for us. (That makes perfect sense.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;As I read more, it seems that as long GitLab’s default shared CI runners do what I need, then I can use them and not worry about installing runners myself. I’d like to see how far I can go with that.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-else-can-i-do&quot;&gt;What Else Can I Do?&lt;/h2&gt;
&lt;p&gt;In order to learn more about the options in GitLab CI configuration, I look at examples at &lt;a href=&quot;https://docs.gitlab.com/ce/ci/examples/README.html&quot; class=&quot;uri&quot;&gt;https://docs.gitlab.com/ce/ci/examples/README.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While poking around, I found that I can specify a Docker image which would have a specific Ruby version installed, so that I could run Jekyll in a controlled environment. I do not have the energy to create a Docker image right now, so I hope that I can just use something simpler. While poking around some more (at &lt;a href=&quot;https://gitlab.com/help/ci/yaml/README.md&quot; class=&quot;uri&quot;&gt;https://gitlab.com/help/ci/yaml/README.md&lt;/a&gt;), I find that I can specify a built-in image for Ruby 2.1. Maybe I can do the same for Ruby 2.3.3, since I’m using that version of Ruby locally.&lt;/p&gt;
&lt;h3 id=&quot;try-running-build-jobs-with-ruby-2.3.3&quot;&gt;Try Running Build Jobs with Ruby 2.3.3&lt;/h3&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT
$ git checkout -b try-specifying-ruby-version
$ mvim .gitlab-ci.yml&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I changed the GitLab CI configuration file in what amounts to a manual microtest. It specifies the Ruby 2.3.3 image and has a single job that merely echoes the Ruby version. I did this on a separate branch to make it easier to switch back to a GitLab CI configuration file that I expect to work.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;image: ruby:2.3.3

check_ruby_version:
  script:
    - ruby --version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I commit and push to the remote repository, wondering whether GitLab CI launches a build on every branch, or merely on receiving something to &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ git add -A
$ git commit -m &amp;quot;We try to run a build job on Ruby 2.3.3.&amp;quot;
$ git push --all gitlab&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, I go back to the &lt;em&gt;Pipelines&lt;/em&gt; page on GitLab to see what happens, if anything. I see a running pipeline, so &lt;em&gt;GitLab CI runs when it receives a push to any branch, and not only &lt;code&gt;master&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Since I have to stop this working session and do something else, let me summarize where we are.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adding a GitLab CI configuration file called &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; to the root of a Git repository activates GitLab CI on that project using the so-called “shared runners”.&lt;/li&gt;
&lt;li&gt;I’ve chosen to ignore the details of shared runners for now, since whatever magic they perform now suffices so far.&lt;/li&gt;
&lt;li&gt;I can specify multiple, parallel—and therefore &lt;em&gt;independent&lt;/em&gt; and &lt;em&gt;isolated&lt;/em&gt;—build jobs, each as a hash with an entry for the key &lt;code&gt;script&lt;/code&gt; that maps to a sequence of bash (or bash-like) commands that perform the job.&lt;/li&gt;
&lt;li&gt;I can specify a single &lt;code&gt;before_script&lt;/code&gt; script that GitLab CI runs before each build job. This script should probably be idempotent and self-contained, because multiple copies of it might run independently.&lt;/li&gt;
&lt;li&gt;I can specify a Docker image to simplify setting up the build job runtime environment, such as with a specific version of Ruby.&lt;/li&gt;
&lt;li&gt;GitLab CI runs no matter which branch I push to, so &lt;code&gt;master&lt;/code&gt; appears not to have any privileged meaning in this regard.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While talking to Sarah about this, we tried to trigger a GitLab CI build by editing a file directly at &lt;a href=&quot;https://gitlab.com&quot; class=&quot;uri&quot;&gt;https://gitlab.com&lt;/a&gt;.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Go to the project at &lt;a href=&quot;https://gitlab.com/jbrains/learn-gitlab-ci&quot; class=&quot;uri&quot;&gt;https://gitlab.com/jbrains/learn-gitlab-ci&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Go to a branch and choose a file. (I only have my GitLab CI configuration file, so I had more of a Hobson’s Choice.)&lt;/li&gt;
&lt;li&gt;Edit the file. I changed the Ruby image to version 2.2.&lt;/li&gt;
&lt;li&gt;Commit the change to a new branch, only because I wanted to keep each manual microtest on a separate branch. This created a merge request, but I actually don’t want to merge this into any existing branch, so I simply went back to the project page.&lt;/li&gt;
&lt;li&gt;Open the &lt;em&gt;Pipelines&lt;/em&gt; page and see a new build job running on the new branch. It installed a GitLab CI runner installing Ruby 2.2, and sure enough, it installed &lt;code&gt;ruby-2.2.6p396&lt;/code&gt;. &lt;strong&gt;Success!&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This means that &lt;em&gt;when we change a file at the GitLab web site, we create a new commit for the project and this triggers a build, just as though we had pushed that change from a different repository&lt;/em&gt;. Good news: we can immediately build each time an individual file changes; bad news: we are forced to immediately build each time an individual file changes. Whether this helps or doesn’t depends on one’s preferences.&lt;/p&gt;
&lt;h2 id=&quot;pushing-to-a-remote-repository&quot;&gt;Pushing To A Remote Repository&lt;/h2&gt;
&lt;p&gt;In order to &lt;em&gt;securely&lt;/em&gt; push to a remote &lt;code&gt;git&lt;/code&gt; repository, I need a way to provide credentials to the remote repository in the little Docker container that GitLab CI uses to run my build jobs. Right off the top of my head, I can envision a few ways to make this work.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The remote repository provider gives me an authorization token that I can use to push to the remote repository.&lt;/li&gt;
&lt;li&gt;I add an SSH key to the remote repository and bundle that key in the local repository.&lt;/li&gt;
&lt;li&gt;I build a custom GitLab CI runner (a Docker container, as far as I can tell so far) that bundles the authorization rights (SSH key, token, whatever) to the remote repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would &lt;em&gt;really&lt;/em&gt; like to avoid the Docker-based solution, because I don’t know Docker well enough to make that work, and I don’t particularly want to learn that today. I can live with, but would prefer not to use the authorization token solution, because then my pipeline depends on knowing details about the deployment destination, more than simply “a &lt;code&gt;git&lt;/code&gt; repository at &lt;em&gt;this&lt;/em&gt; address”. I don’t know how to bundle an SSH key in my local repository, because I usually use the default location of SSH keys (&lt;code&gt;\$HOME/.ssh&lt;/code&gt;). No matter what I choose, I’m not going to like it.&lt;/p&gt;
&lt;p&gt;In this situation, unless someone gives me a more suitable idea, I’ll opt for the solution that requires the least obtrusive work, at least for now. I know that I first want to push to a Heroku repository, so I can start by exploring how to push to a Heroku repository with a token instead of an SSH key.&lt;/p&gt;
&lt;h3 id=&quot;pushing-to-a-heroku-repository-without-an-ssh-key&quot;&gt;Pushing To A Heroku Repository Without An SSH Key&lt;/h3&gt;
&lt;p&gt;I’d like to try this without going through GitLab CI, since doing that slows down my feedback cycle. I think I can get this working first using my local environment, and then try to replicate it in a GitLab CI pipeline build job. Certainly, if I can’t get it working locally, then I don’t have a chance of getting it to work in GitLab CI.&lt;/p&gt;
&lt;p&gt;I need to create a Heroku app, ask Heroku to generate some kind of authorization token that lets me push to that app, &lt;em&gt;don’t&lt;/em&gt; set up an SSH key that lets me push to that app, then use the token to push to that app from a local &lt;code&gt;git&lt;/code&gt; repository. My first test can consist of creating the Heroku app, and then verifying that I &lt;em&gt;can’t&lt;/em&gt; push to it, even with the SSH key that is configured for my Heroku account. I don’t know whether this is even possible. I would hate to &lt;em&gt;accidentally&lt;/em&gt; have authorization to push to this Heroku app, since I definitely wouldn’t have that in my GitLab CI environment.&lt;/p&gt;
&lt;p&gt;First, I visit &lt;a href=&quot;https://www.heroku.com&quot; class=&quot;uri&quot;&gt;https://www.heroku.com&lt;/a&gt;, log in, and then create a simple app that does nothing. I only care that I can or can’t push to this repository using &lt;code&gt;git&lt;/code&gt; from my local environment command line. I don’t need the app to actually do anything on the web, and nobody will ever know that it exists.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $WORKSPACE_ROOT
$ git init learn-pushing-to-heroku-without-ssh-keys
$ cd learn-pushing-to-heroku-without-ssh-keys
# I&amp;#39;ll call this folder CHECK_PUSH_PROJECT_ROOT
$ heroku apps:create try-pushing-without-ssh-keys
$ git remote -v
heroku  https://git.heroku.com/try-pushing-without-ssh-keys.git (fetch)
heroku  https://git.heroku.com/try-pushing-without-ssh-keys.git (push)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I notice that, by default, Heroku adds the remote repository using secure HTTP Git transport, rather than SSH Git transport. This leads me to &lt;a href=&quot;https://devcenter.heroku.com/articles/git&quot; class=&quot;uri&quot;&gt;https://devcenter.heroku.com/articles/git&lt;/a&gt; where I read (in the section &lt;a href=&quot;https://devcenter.heroku.com/articles/git#http-git-authentication&quot; class=&quot;uri&quot;&gt;https://devcenter.heroku.com/articles/git#http-git-authentication&lt;/a&gt;) that with HTTP Git authentication, I can’t use SSH keys, but rather only Heroku API keys for authentication. Good! This already matches what I think I want. In order to check that I understand this, pushing to this remote should already fail.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd CHECK_PUSH_PROJECT_ROOT
$ git commit --allow-empty -m &amp;quot;Test 1, pushing without SSH keys.&amp;quot;
$ git push heroku master
Counting objects: 2, done.
Writing objects: 100% (2/2), 186 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: error: pathspec &amp;#39;.&amp;#39; did not match any file(s) known to git.
remote: 
remote: !       Heroku Git error, please try again shortly.
remote: !       See https://status.heroku.com for current Heroku platform status.
remote: !       If the problem persists, please open a ticket
remote: !       on https://help.heroku.com/tickets/new
remote: !       and provide the Request ID [redacted]
remote: 
To https://git.heroku.com/try-pushing-without-ssh-keys.git
 ! [remote rejected] master -&amp;gt; master (pre-receive hook declined)
error: failed to push some refs to &amp;#39;https://git.heroku.com/try-pushing-without-ssh-keys.git&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hm. Good news: push failed; bad news: the error message describes a failure other than the one I’m expecting. I’d prefer a message that more directly points to the problem. This could mean that I encountered a transitory failure, so I try again, giving the same result. This makes it more likely that either I’m failing to push for the right reason with a terrible error message &lt;em&gt;or&lt;/em&gt; Heroku happens to be having some problems right now. To rule out the second possibility, I check Heroku’s status by visiting &lt;a href=&quot;https://status.heroku.com/&quot; class=&quot;uri&quot;&gt;https://status.heroku.com/&lt;/a&gt;. The status report claims that everything is working, so if Heroku has a problem, then Heroku hasn’t noticed yet. For the moment, then, I have to assume that my push is failing for the right reason, and now I need to learn how to specify my Heroku API key so that I have authorization to push to my Heroku repository. For this, I go back to reading &lt;a href=&quot;https://devcenter.heroku.com/articles/git#http-git-authentication&quot; class=&quot;uri&quot;&gt;https://devcenter.heroku.com/articles/git#http-git-authentication&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This articles tells me that everything should “work transparently” from my local environment, because I have previously used &lt;code&gt;heroku login&lt;/code&gt; to establish my credentials with Heroku. I checked this by removing &lt;code&gt;heroku&lt;/code&gt; references from &lt;code&gt;\$HOME/.netrc&lt;/code&gt;, trying to push from the command line, and seeing Heroku ask me for a password. In other words, as soon as I use &lt;code&gt;heroku login&lt;/code&gt;, Heroku considers me authenticated and lets me push from this environment. I don’t want that, because I can’t (and don’t want to) type my Heroku password into a GitLab CI job in order to authenticate myself with Heroku. I need to know how to specify my Heroku API key some other way when pushing to Heroku. Sadly, the document I’m reading now doesn’t tell me how to do that.&lt;/p&gt;
&lt;p&gt;Fortunately, Stack Overflow gives me a clue. It tells me that I could try something like the following&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to test this, I first try doing this even with my Heroku credentials present in &lt;code&gt;.netrc&lt;/code&gt;, to make sure that that works; and then I remove the Heroku credentials from &lt;code&gt;.netrc&lt;/code&gt; to check whether that also works.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ git push &amp;quot;https://heroku:$(heroku auth:token)@git.heroku.com/try-pushing-without-ssh-keys.git&amp;quot; master
Counting objects: 2, done.
Writing objects: 100% (2/2), 186 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: error: pathspec &amp;#39;.&amp;#39; did not match any file(s) known to git.
remote: 
remote: !       Heroku Git error, please try again shortly.
remote: !       See https://status.heroku.com for current Heroku platform status.
remote: !       If the problem persists, please open a ticket
remote: !       on https://help.heroku.com/tickets/new
remote: !       and provide the Request ID [redacted]
remote: 
To https://git.heroku.com/try-pushing-without-ssh-keys.git
 ! [remote rejected] master -&amp;gt; master (pre-receive hook declined)
error: failed to push some refs to &amp;#39;https://heroku:[my-heroku-api-key]@git.heroku.com/try-pushing-without-ssh-keys.git&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Interesting! This tells me that the error message I saw probably has nothing to do with authentication, and that I need to fix that first.&lt;/p&gt;
&lt;h3 id=&quot;chasing-a-rabbit&quot;&gt;Chasing A Rabbit&lt;/h3&gt;
&lt;p&gt;One thing leaps to my mind: I have no files in this repository, just an empty commit, and perhaps Heroku does something in its standard &lt;code&gt;pre-receive&lt;/code&gt; hook that assumes that there are file in the repository. I spend about 30 seconds searching the web looking for confirmation of this guess before trying to add files to the repository. I also conjecture that perhaps I need a minimally-viable Heroku app in order to pass Heroku’s &lt;code&gt;pre-receive&lt;/code&gt; check, so I might need to create something like a valid &lt;code&gt;Procfile&lt;/code&gt; that just echoes “Hello, world!” to &lt;code&gt;stdout&lt;/code&gt; in order for Heroku to accept my push. Right now, &lt;em&gt;I don’t know the contract for Heroku to agree to accept my push&lt;/em&gt;. I need to reverse-engineer some aspect of it. &lt;em&gt;Undocumented contracts kill.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I couldn’t find anything definitive quickly, but from what I read, I infer that the error happens when Heroku tries to run &lt;code&gt;git checkout&lt;/code&gt; on the repository, so I try to mimic the conditions under which &lt;code&gt;git checkout&lt;/code&gt; would generate the error &lt;code&gt;error: pathspec &apos;.&apos; did not match any file(s) known to git.&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $CHECK_PUSH_PROJECT_ROOT
$ git checkout master
# That works
$ git checkout .
error: pathspec &amp;#39;.&amp;#39; did not match any file(s) known to git.
# Interesting! Does this always happen, or does this relate to not having any files?
$ git checkout -b diagnose-git-pathspec-error
Switched to a new branch &amp;#39;diagnose-git-pathspec-error&amp;#39;
$ touch i_need_a_file.txt
$ git add -A
$ git commit -m &amp;quot;I need a file to see what happens when I try to checkout the current directory.&amp;quot;
$ git checkout .
# That works!
$ git checkout master
# There are no files on this branch.
$ git checkout .
error: pathspec &amp;#39;.&amp;#39; did not match any file(s) known to git.
# Aha!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OK, so it seems that Heroku’s &lt;code&gt;pre-receive&lt;/code&gt; hook &lt;em&gt;assumes&lt;/em&gt; that there are files in the branch that we push to it. Good to know.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don’t get me wrong: “files exist on this branch” is a perfectly reasonable requirement in the contract for a module consuming a push from another Git repository; but it would be even nicer if either (1) the receiving repository didn’t have this requirement or (2) the receiving repository produced a better message when someone violates the contract.&lt;/p&gt;
&lt;p&gt;This feels similar to a function that accepts a collection, and then fails when it receives an empty collection, even though it could safely silently do nothing in that case. Worse, when that function fails with a generic “no such element” error.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now I feel more confident that, if I add a file to this repository, then push, that the push will pass Heroku’s &lt;code&gt;pre-receive&lt;/code&gt; hook and I’ll more easily distinguish an authentication success from an authentication failure. Just for the sake of avoiding another rabbit-hole, I’ll add a &lt;code&gt;Procfile&lt;/code&gt; that does nothing interesting.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# Procfile
web: echo &amp;quot;Hello, world&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $CHECK_PUSH_PROJECT_ROOT
$ git add -A
$ git commit -m &amp;quot;Heroku won&amp;#39;t accept a push unless the branch has files on it.&amp;quot;
$ git push &amp;quot;https://heroku:$(heroku auth:token)@git.heroku.com/try-pushing-without-ssh-keys.git&amp;quot; master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 459 bytes | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote:  !     No default language could be detected for this app.
remote:                         HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.
remote:                         See https://devcenter.heroku.com/articles/buildpacks
remote: 
remote:  !     Push failed
remote: Verifying deploy....
remote: 
remote: !       Push rejected to try-pushing-without-ssh-keys.
remote: 
To https://git.heroku.com/try-pushing-without-ssh-keys.git
 ! [remote rejected] master -&amp;gt; master (pre-receive hook declined)
error: failed to push some refs to &amp;#39;https://heroku:[my-heroku-api-key]@git.heroku.com/try-pushing-without-ssh-keys.git&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OK… I can live with this. Although Heroku rejects the app, &lt;em&gt;it is clear enough to me for right now&lt;/em&gt; that authentication has succeeded—which I had as a goal—and I don’t care enough to explore how to build a minimal Heroku app, which appears to involve &lt;em&gt;at least&lt;/em&gt; specifying a buildpack. For now, I will interpret this result as “authentication passed”, and as long as I can confidently interpret a result as having got past the authentication step, I won’t push for a more obvious success response.&lt;/p&gt;
&lt;p&gt;Now… where was I? Oh yes, &lt;em&gt;we can push to Heroku using the API Key, as long as we also have the right Heroku credentials stored in the local environment&lt;/em&gt;, in this case, in the file &lt;code&gt;\$HOME/.netrc&lt;/code&gt; from having previously successfully logged in to Heroku using the Heroku CLI tool. Now, let’s weaken the assumption.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ heroku logout
Local credentials cleared.
$ git push https://git.heroku.com/try-pushing-without-ssh-keys.git master
[Evidence that we connected, and so authentication passed.]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;FAILED. I don’t know whether this means that I somehow still magically have credentials stored locally (where?!) &lt;em&gt;or&lt;/em&gt; that Heroku is remembering my previously-successful authentication. I can check the latter by destroying the Heroku app and creating a new one, then trying to push to the new Heroku app without the Heroku API key, and expecting authentication to fail.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ heroku login
[Enter credentials...]
$ heroku apps:delete try-pushing-without-ssh-keys --confirm try-pushing-without-ssh-keys
Destroying ⬢ try-pushing-without-ssh-keys (including all add-ons)... done
$ heroku logout
Local credentials cleared.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, &lt;em&gt;just to be sure&lt;/em&gt;, I create the Heroku app on the web, so that I don’t accidentally store my Heroku credentials locally. I created an app called &lt;code&gt;try-pushing-with-api-key&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $CHECK_PUSH_PROJECT_ROOT
$ git push https://git.heroku.com/try-pushing-with-api-key.git master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…and that worked just fine, too. This leads me to conclude either that Heroku is remembering my authentication with the API key &lt;em&gt;or&lt;/em&gt; that HTTPS Git transport lets me push without authentication. Now, it makes sense to me that, since HTTPS Git transport uses HTTP basic authentication, that there is some period during which Heroku’s server remembers my authentication credentials, which normally helps me, but right now hurts me. Of course, I don’t know this timeout period, so I have no idea how long to wait until I can try this again and get responses that I expect and can safely interpret. If I had to guess, I’d say 15 or 30 minutes, maybe 1 hour.&lt;/p&gt;
&lt;p&gt;Annoying. I guess I have to wait for 2 hours, just to be sure that Heroku’s server has forgot my credentials.&lt;/p&gt;
&lt;p&gt;Well… let me check this. If I can push to this repository over HTTPS Git transport from the GitLab CI runner, then that changes the game on me, and I’d rather learn that now than wait 2 hours to run yet another inconclusive test.&lt;/p&gt;
&lt;p&gt;Even better, before I go through all that, I probably only need to push to this Heroku repository &lt;em&gt;from a different IP address&lt;/em&gt;, because Heroku wouldn’t associate that client with my currently-cached credentials. I don’t have to go through GitLab CI for this; I can use my Rackspace account, because that machine does not reside behind my home router.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ ssh [my-rackspace-account-address]
$ cd $WORKSPACE_ROOT
$ git init try-pushing-to-heroku-from-somewhere-else
$ cd try-pushing-to-heroku-from-somewhere-else
$ git push https://git.heroku.com/try-pushing-with-api-key.git master
# Oops, there&amp;#39;s probably not even a master branch yet.
$ git branch
# nothing
$ git commit --allow-empty -m &amp;quot;Create me a master branch, please.&amp;quot;

*** Please tell me who you are.

Run

  git config --global user.email &amp;quot;you@example.com&amp;quot;
  git config --global user.name &amp;quot;Your Name&amp;quot;

to set your account&amp;#39;s default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for &amp;lt;jbrains@quincy.(none)&amp;gt;) not allowed
# Ugh! I&amp;#39;ll add an identity just for this repository.
$ git config user.email &amp;quot;me@jbrains.ca&amp;quot;
$ git config user.name &amp;quot;J. B. Rainsberger&amp;quot;
# Try again.
$ git commit --allow-empty -m &amp;quot;Create me a master branch, please.&amp;quot;
# Done.
$ git branch
* master
$ git push https://git.heroku.com/try-pushing-with-api-key.git master
Username for &amp;#39;https://git.heroku.com&amp;#39;: 
[CTRL+C]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PASSED. Heroku’s server correctly demanded a password, so it is almost certainly the case that Heroku has cached credentials related to my local environment, and I can’t continue testing from my local environment until Heroku removes those credentials from its cache. However, I &lt;em&gt;can&lt;/em&gt; use my Rackspace account to try pushing with the Heroku API key, since Heroku clearly isn’t magically authenticating me some other way.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# Still logged in to my Rackspace account
$ git push https://heroku:[my-heroku-api-key]@git.heroku.com/try-pushing-with-api-key.git master
Counting objects: 2, done.
Writing objects: 100% (2/2), 180 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: error: pathspec &amp;#39;.&amp;#39; did not match any file(s) known to git.
# ...and so on&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PASSED. Authentication passed, even though Heroku rejected the push because it has no files.&lt;/p&gt;
&lt;h3 id=&quot;the-thrilling-conclusion&quot;&gt;The Thrilling Conclusion&lt;/h3&gt;
&lt;p&gt;In order to push to a Heroku Git repository with just the Heroku API key, do this:&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $YOUR_PROJECT_ROOT
$ git push https://heroku:$(HEROKU_API_KEY)@git.heroku.com/$(HEROKU_APP_NAME).git $(LOCAL_BRANCH_TO_PUSH)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wonderful! I can easily do this. Now, &lt;em&gt;in order to feel the feeling of completion&lt;/em&gt;, I want to try this right away!&lt;/p&gt;
&lt;h2 id=&quot;pushing-to-heroku-from-gitlab-ci&quot;&gt;Pushing To Heroku From GitLab CI&lt;/h2&gt;
&lt;p&gt;In order to make this work more nicely, I’d like Heroku to accept the push, which means delivering a minimal Heroku app. For this, I added the Ruby buildpack to my Heroku app and I created a &lt;code&gt;Procfile&lt;/code&gt; that ran a “Hello, world” app using Ruby.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# Procfile
worker: bundle exec ruby -e &amp;quot;puts &amp;#39;Hello, world.&amp;#39;&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If this fails, then at least I can try the same thing from my local microtesting environment, and then figure out how to make it run through GitLab CI. I have, however, become impatient for a final result, so I’ll try running this directly in GitLab CI and hope for the best. This step either ends my learning or leads to taking a long break involving alcohol.&lt;/p&gt;
&lt;p&gt;This time, however, I have to be careful, because Heroku wants me to push to the branch &lt;code&gt;master&lt;/code&gt;, but I’ve been using various branches for various tests, so I need to control the branch I’m on.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# .gitlab-ci.yml
before_script:
  - git config user.email &amp;quot;gitlab-ci-client@jbrains.ca&amp;quot;
  - git config user.name &amp;quot;GitLab CI on behalf of J. B. Rainsberger&amp;quot;

push_to_heroku:
  script:
    # I need to control which Git branch I&amp;#39;m on in order to push to Heroku
    - git checkout -b publish-to-heroku
    - git commit --allow-empty -m &amp;quot;Test pushing to Heroku at $(date)&amp;quot;
    - git branch -v
    - git push https://heroku:[my-heroku-api-key]@git.heroku.com/try-pushing-with-api-key.git publish-to-heroku:master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now…&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ cd $PROJECT_ROOT
$ git add -A
$ git status -s
M  .gitlab-ci.yml
A  Procfile
$ git commit -m &amp;quot;Test deploying a dead-simple Ruby app from GitLab CI to Heroku&amp;quot;
$ git push --all gitlab
$ open https://gitlab.com/jbrains/learn-gitlab-ci/pipelines?scope=running&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PASSED.&lt;/p&gt;
&lt;p&gt;Here is the contract of using GitLab CI to deploy to Heroku, as far as I can tell.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The GitLab CI build job has to control or detect which branch it’s on in order to push the correct branch to Heroku as &lt;code&gt;master&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The build job has to push an app that Heroku can detect, build, and run. (Clearly.)&lt;/li&gt;
&lt;li&gt;The build job has to push to Heroku using the Heroku API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before declaring victory, however, there remains the problem of hardcoding the Heroku API key in my GitLab CI configuration file. I will need to come back and read &lt;a href=&quot;https://docs.gitlab.com/ce/ci/variables/README.html#secret-variables&quot; class=&quot;uri&quot;&gt;https://docs.gitlab.com/ce/ci/variables/README.html#secret-variables&lt;/a&gt; to learn more about that. For now, it’s time for a break.&lt;/p&gt;
&lt;h4 id=&quot;future-work&quot;&gt;Future Work&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Introduce secret variable for the Heroku API key.&lt;/li&gt;
&lt;li&gt;Introduce a “production” environment to make room for things like staging/preview/whatever.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;keeping-the-heroku-api-key-secret&quot;&gt;Keeping the Heroku API Key Secret&lt;/h3&gt;
&lt;p&gt;According to the documentation at &lt;a href=&quot;https://docs.gitlab.com/ce/ci/variables/README.html#secret-variables&quot; class=&quot;uri&quot;&gt;https://docs.gitlab.com/ce/ci/variables/README.html#secret-variables&lt;/a&gt;, I change a GitLab-project-level setting, listed under &lt;strong&gt;Settings &amp;gt; CI/CD Pipeline &amp;gt; Secret Variables&lt;/strong&gt;. (I had to contribute to GitLab’s documentation in order to clarify where to find that setting, since it had moved.) I introduced the Heroku API Key as a secret variable, then changed the GitLab CI configuration file accordingly.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# .gitlab-ci.yml
before_script:
  - git config user.email &amp;quot;gitlab-ci-client@jbrains.ca&amp;quot;
  - git config user.name &amp;quot;GitLab CI on behalf of J. B. Rainsberger&amp;quot;

push_to_heroku:
  script:
    # I need to control which Git branch I&amp;#39;m on in order to push to Heroku
    - git checkout -b publish-to-heroku
    - git commit --allow-empty -m &amp;quot;Test pushing to Heroku at $(date)&amp;quot;
    - git branch -v
    - git push --force https://heroku:$HEROKU_API_KEY@git.heroku.com/try-pushing-with-api-key.git publish-to-heroku:master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I should note that I also had to add &lt;code&gt;--force&lt;/code&gt; to my &lt;code&gt;git push&lt;/code&gt; command, because I’m not necessarily keeping my local repository synchronized with the Heroku app’s repository.&lt;/p&gt;
&lt;h2 id=&quot;i-think-i-have-all-the-pieces&quot;&gt;I Think I Have All The Pieces&lt;/h2&gt;
&lt;p&gt;Now, I think I have all the pieces to do the thing that I wanted to do with GitLab CI in the first place. I think I’m ready to run an end-to-end test. For that, I need the following.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Jekyll project in my local development environment.&lt;/li&gt;
&lt;li&gt;A GitLab repository to act as the intermediary between development and production.&lt;/li&gt;
&lt;li&gt;A Heroku app able to run Jekyll as a Rack app, for which the Rack/Jekyll buildpack will come in handy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;create-a-local-jekyll-project&quot;&gt;Create A Local Jekyll Project&lt;/h3&gt;
&lt;p&gt;I chose a Jekyll theme arbitrarily, just for interest.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In my local environment, which is my MacBook
$ cd $WORKSPACE_ROOT
$ git clone https://github.com/lukas-h/onepage.git try-deploy-jekyll-to-heroku-through-gitlab
$ cd try-deploy-jekyll-to-heroku-through-gitlab
# Does it work at all?
# There&amp;#39;s no Gemfile. Weird. Let&amp;#39;s create one.&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# Gemfile
source &amp;quot;https://rubygems.org&amp;quot;

ruby &amp;quot;2.3.3&amp;quot;

gem &amp;quot;jekyll&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ bundle install
# Bundler easily installs gems.
$ bundle exec jekyll serve
# Open https://127.0.0.1:4000 in a browser
# It works!
$ git add -A
$ git commit -m &amp;quot;We can now serve the Jekyll site.&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that I’ve confirmed that the Jekyll app works, it’s time to prepare it for deployment to Heroku, by making it a Rack app.&lt;/p&gt;
&lt;p&gt;I visited &lt;a href=&quot;https://adaoraul.github.io/rack-jekyll/&quot; class=&quot;uri&quot;&gt;https://adaoraul.github.io/rack-jekyll/&lt;/a&gt; and followed the instructions: adding the gem and creating &lt;code&gt;config.ru&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# Gemfile
source &amp;quot;https://rubygems.org&amp;quot;

ruby &amp;quot;2.3.3&amp;quot;

gem &amp;quot;jekyll&amp;quot;
gem &amp;quot;rack-jekyll&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# config.ru
require &amp;quot;rack/jekyll&amp;quot;
run Rack::Jekyll.new&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# _config.yml
# skip a bunch of stuff...
exclude:
  - LICENSE
  - README.md
  - vendor
  - Gemfile
  - Gemfile.lock
  - config.ru&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In the local environment
$ bundle install
# Bundler installs Rack/Jekyll
# Does it work?
$ bundle exec rackup
# Open https://127.0.0.1:9292 in a browser
# It works!
$ git add -A
$ git commit -m &amp;quot;We can now serve the Jekyll site as a Rack app&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;create-a-heroku-app&quot;&gt;Create a Heroku App&lt;/h3&gt;
&lt;p&gt;I visited &lt;a href=&quot;https://www.heroku.com&quot; class=&quot;uri&quot;&gt;https://www.heroku.com&lt;/a&gt; and created an app named &lt;code&gt;arbitrary-jekyll-site&lt;/code&gt;, to which I added the buildpack at &lt;a href=&quot;https://github.com/heroku/heroku-buildpack-ruby.git&quot; class=&quot;uri&quot;&gt;https://github.com/heroku/heroku-buildpack-ruby.git&lt;/a&gt;. I visited &lt;a href=&quot;https://arbitrary-jekyll-site.herokuapp.com/&quot; class=&quot;uri&quot;&gt;https://arbitrary-jekyll-site.herokuapp.com/&lt;/a&gt; to verify that the Heroku app works at all. Next, I verify that I can deploy to Heroku from my local environment.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In the local environment
$ export HEROKU_API_KEY=none-of-your-business
$ git remote add production https://heroku:$HEROKU_API_KEY@git.heroku.com/arbitrary-jekyll-site.git
$ git push production master
# Open https://arbitrary-jekyll-site.herokuapp.com/ in a browser&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It works!&lt;/p&gt;
&lt;h3 id=&quot;create-a-gitlab-project&quot;&gt;Create a GitLab Project&lt;/h3&gt;
&lt;p&gt;I visited &lt;a href=&quot;https://www.gitlab.com&quot; class=&quot;uri&quot;&gt;https://www.gitlab.com&lt;/a&gt; and created a GitLab project called &lt;code&gt;deploy-jekyll-to-heroku-using-gitlab-ci&lt;/code&gt;. I then added it as a remote to the Jekyll project in my local environment.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In the local environment
$ git remote add gitlab git@gitlab.com:jbrains/deploy-jekyll-to-heroku-using-gitlab-ci.git
# Let&amp;#39;s see if this works at all!
$ git push --all -u gitlab
# Yay!&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;set-up-gitlab-ci&quot;&gt;Set Up GitLab CI&lt;/h3&gt;
&lt;p&gt;First, I set up the secret variable representing the Heroku API key under the new GitLab project CI/CD pipeline.&lt;/p&gt;
&lt;p&gt;Next, I can use that secret variable to configure GitLab CI.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# .gitlab-ci.yml
before_script:
  - git config user.email &amp;quot;gitlab-ci-client@jbrains.ca&amp;quot;
  - git config user.name &amp;quot;GitLab CI on behalf of J. B. Rainsberger&amp;quot;

push_to_heroku:
  variables:
    # I need to control which Git branch I&amp;#39;m on in order to push to Heroku
    publication_branch_name: &amp;quot;publish-to-heroku&amp;quot;

  script:
    - git checkout -b $publication_branch_name
    - git commit --allow-empty -m &amp;quot;Publish to Heroku at $(date)&amp;quot;
    - git push --force https://heroku:$HEROKU_API_KEY@git.heroku.com/arbitrary-jekyll-site.git $publication_branch_name:master&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I commit everything and push it to GitLab, then wait for the fireworks!&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;$ git add -A
$ git commit -m &amp;quot;GitLab CI now deploys to Heroku.&amp;quot;
$ git push gitlab&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I wait two minutes for the GitLab CI pipeline to finish its work. With any luck, we see evidence of a new Heroku deployment.&lt;/p&gt;
&lt;p&gt;…and we do! I visit &lt;a href=&quot;https://arbitrary-jekyll-site.herokuapp.com/&quot; class=&quot;uri&quot;&gt;https://arbitrary-jekyll-site.herokuapp.com/&lt;/a&gt; in my browser and see a web application.&lt;/p&gt;
&lt;h2 id=&quot;change-the-jekyll-site-change-the-production-web-site&quot;&gt;Change The Jekyll Site, Change The Production Web Site&lt;/h2&gt;
&lt;p&gt;This remains the final end-to-end test before I declare victory.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In the local environment
$ mvim _posts/2017-02-13-hello-world.markdown&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;# _posts/2017-02-13-hello-world.markdown
---
title: &amp;quot;Hello, World!&amp;quot;
date: 2017-02-13
---
# Hello, World!&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In the local environment
$ bundle exec jekyll serve
# Open https://localhost:4000/ and check for the new post
# I see it!
[CTRL+C]
$ git add -A
$ git commit -m &amp;quot;Wrote a shiny new post.&amp;quot;
$ git push gitlab
# Wait two minutes
# Open https://arbitrary-jekyll-site.herokuapp.com/ and check for the new post
# I see it!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally… it all works.&lt;/p&gt;
&lt;h2 id=&quot;clean-up-before-moving-on&quot;&gt;Clean Up Before Moving On&lt;/h2&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# In the local environment
$ git remote rm production
# ...because now GitLab does this for us
$ git remote rm origin
# ...because I don&amp;#39;t intend to contribute back to the theme
$ git remote -v
gitlab  git@gitlab.com:jbrains/deploy-jekyll-to-heroku-using-gitlab-ci.git (fetch)
gitlab  git@gitlab.com:jbrains/deploy-jekyll-to-heroku-using-gitlab-ci.git (push)
# That&amp;#39;s it!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I finish by removing the Heroku apps and GitLab projects that I no longer need. Now I can do this for real, and after I do it for real, then I can remove these test apps and projects. This document should suffice for recreating everything if I need to.&lt;/p&gt;
&lt;p&gt;That was almost fun.&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Feb 2017 19:16:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/deploying-jekyll-to-heroku-using-gitlab-ci</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/deploying-jekyll-to-heroku-using-gitlab-ci</guid>
        
        
        <category>Tutorials</category>
        
      </item>
    
      <item>
        <title>No More Boilerplate Code</title>
        <description>&lt;p&gt;The name &lt;strong&gt;template method&lt;/strong&gt; is a perfect example of a structural name: it describes the implementation rather than the meaning or purpose. This is what happens when programmers name things.&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;We have standard workflows in our systems that programmers copy and paste from module to module in order to achieve some kind of standard behavior. Programmers call this &lt;em&gt;boilerplate&lt;/em&gt;. Programmers tend to copy and paste this code because —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They don’t see the duplication, because usually not much code is duplicated.&lt;/li&gt;
&lt;li&gt;Even if they see the duplication, they don’t know how to remove the duplication, because they can’t just highlight code and hit “Extract Method” in their refactoring tool.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Functional programmers tend to notice this duplication better than object-oriented programmers, because they more easily think of functions as potential parameters to a block of code.&lt;/p&gt;
&lt;h2 id=&quot;a-solution&quot;&gt;A Solution&lt;/h2&gt;
&lt;p&gt;To extract the standard workflow, identity the steps, extract each of them into a function, leaving behind the workflow (or &lt;em&gt;template&lt;/em&gt;). Once the duplication in the workflow becomes obvious, extract a function whose parameters are the steps. You can now add similar features by combining the standard workflow with newly-implemented steps.&lt;/p&gt;
&lt;h2 id=&quot;an-example&quot;&gt;An Example&lt;/h2&gt;
&lt;p&gt;There is a standard workflow for executing a query on an SQL database in Java:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Start with a Data Source.&lt;/li&gt;
&lt;li&gt;Ask the Data Source for a Connection.&lt;/li&gt;
&lt;li&gt;Ask the Connection for a Prepared Statement.
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Tell the Prepared Statement about the query that you wish to execute:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select * from products where products.id = ?&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;For the parameter placeholder, use the ID &lt;code&gt;17923&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ask the Prepared Statement to execute the query, which returns a Result Set.&lt;/li&gt;
&lt;li&gt;We expect exactly one row, because our SQL statement filters on a primary key column, so if there is no row in the result set, then return an answer that represents “no product”. (Null Object? null reference? Exception? You decide.) The rest of the way, we can assume that there is at least one row.&lt;/li&gt;
&lt;li&gt;Ask the Result Set to advance to the first row.&lt;/li&gt;
&lt;li&gt;Ask the Result Set (now pointing to the first row) for the values of the various columns and use that information to create a Product object.&lt;/li&gt;
&lt;li&gt;Ask the Result Set to advance to the next row. If you find a next row, then throw an Exception communicating “We found too many rows, and that’s weird, because we thought we were finding rows by a primary key, and there should be just one matching row. The table in question is &lt;code&gt;products&lt;/code&gt;, which is probably missing a uniqueness constraint. Check the DDL. Good luck.” The rest of the way, we can assume that there is exactly one row.&lt;/li&gt;
&lt;li&gt;Now that we have our Product object, we need to clean up:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Close the Result Set, and if anything goes wrong, signal a warning about it, but keep going, because there’s nothing we can do about it now.&lt;/li&gt;
&lt;li&gt;Close the Prepared Statement, and if anything goes wrong, signal a warning about it, but keep going, because there’s nothing we can do about it now.&lt;/li&gt;
&lt;li&gt;Close the Connection, and if anything goes wrong, signal a warning about it, but keep going, because there’s nothing we can do about it now.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Return the Product as our final answer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I call most of this “JDBC noise”, because, well, that’s what it is. It’s a noisy API. I don’t consider this a problem, but rather just a fact: in order to add flexibility, we have to add noise. I don’t know how to do it any other way. Sadly, however, most people do the same things the same way all the time… &lt;em&gt;almost&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;some-problems-with-this-code&quot;&gt;Some Problems With This Code&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Some programmers are very optimistic&lt;/strong&gt; and don’t protect against the situation where a primary key query — more correctly, &lt;em&gt;what they believed was a primary key query&lt;/em&gt; — matches multiple rows. &lt;em&gt;It should never happen&lt;/em&gt;, but it might happen, and we should probably do better than merely matching the row that the database happens to put first in the list. If we think we’re running a primary key query and the database finds multiple matching rows, &lt;em&gt;that’s a mistake somewhere&lt;/em&gt;, and we need to detect the mistake so that we can fix it. It’s probably a simple typo in the DDL, but it could damage production data. I’d prefer to be able to detect this problem in the standard workflow, because &lt;em&gt;if we check it in some places and not others, then we either waste a lot of energy duplicating defensive code (and rememering to duplicate defensive code and complaining about duplicating defensive code) or we waste a lot of energy under pressure assuming that this situation can’t happen and then wondering how the hell it’s happening now, at 3 AM, when I’m supposed to be sleeping on vacation. I had a long day of relaxing on the beach planned!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some programmers are inexperienced&lt;/strong&gt; and don’t close their result sets, statements, and connections, and this leaks resources. This slows down the application and encourages other, more experienced programmers to show how clever they are about performance optimization. This leads to wasting energy trying to understand clever code instead of relaxing on the beach.&lt;/p&gt;
&lt;h3 id=&quot;the-main-difficulty-with-this-code&quot;&gt;The Main Difficulty With This Code&lt;/h3&gt;
&lt;p&gt;Many programmers just assume that they have to copy and paste the JDBC noise throughout their system because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The duplicated code is interspersed with the unique code, so how do we tear these two things apart? I can see how to pass the SQL query as a parameter, because it’s just a String, but what about the rest?&lt;/li&gt;
&lt;li&gt;The unique steps look really different: the way to turn an SQL Result Set row into a Product differs a lot from turning a row into a Customer or an Order or any of the other 26 domain objects we have.&lt;/li&gt;
&lt;li&gt;Even the return type of the function depends on the domain object type! How do we even create a standard type signature?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some programmers see how to deal with these difficulties and others don’t. In this particular case, the programmer needs to see different kinds of duplication, know how to make similar code even more similar, and then see how to remove the duplication. Not everyone knows how to do this. Fortunately, everyone can learn.&lt;/p&gt;
&lt;h2 id=&quot;the-general-algorithm&quot;&gt;The General Algorithm&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Find similar blocks of code or functions and look at them all together.&lt;/li&gt;
&lt;li&gt;Identify the identical steps, the similar steps, and the different steps. (There might not be steps in all three categories.) The identical steps are identical code; the similar steps differ only in data parameters; the different steps look, well, different.&lt;/li&gt;
&lt;li&gt;Extract functions for the identical steps. If you’re extracting &lt;em&gt;methods&lt;/em&gt;, then it’s possible for the identical steps to operate only on fields of the object and not need any extra parameters. If there are several identical steps in succession and they obviously belong together, then don’t bother separating them just yet. (You might do this later.)&lt;/li&gt;
&lt;li&gt;Extract functions for the similar steps. Even if you’re extracting &lt;em&gt;methods&lt;/em&gt;, it’s likely that these functions require parameters for the data that differs among the original functions. In our database example, the SQL query is different for each query, even though the general shape of &lt;code&gt;select * from &amp;lt;table&amp;gt; where &amp;lt;id&amp;gt; = ?&lt;/code&gt; is the same for each one. (There’s a clue.)&lt;/li&gt;
&lt;li&gt;Extract functions for the different steps. With any luck, the functions that you extract will all have an identical shape. With less luck, they’ll have similar shape, such as having the same input parameters, but a different return type. If they have drastically different shapes, then we have to use a trick that I’ll describe later.&lt;/li&gt;
&lt;li&gt;After extracting functions for the various steps — the &lt;em&gt;steps&lt;/em&gt; of the workflow — you should have left behind very similar workflows in the original blocks of code. You might have chosen identical names or, at worst, similar names. You should be able to see an obvious pattern in the names of the steps. Take some time to make the pattern more obvious, such as by renaming the steps to follow a common naming scheme.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;identical-steps-in-our-example&quot;&gt;Identical Steps in Our Example&lt;/h2&gt;
&lt;p&gt;I have highlighted the identical steps in our example. They correspond to literally identical lines of code.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Data Source for a Connection.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Connection for a Prepared Statement.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tell the Prepared Statement about the query that you wish to execute:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;select * from products where products.id = ?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For the parameter placeholder, use the ID &lt;code&gt;17923&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Prepared Statement to execute the query, which returns a Result Set.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;We expect exactly one row, because our SQL statement filters on a primary key column, so if there is no row in the result set, then return an answer that represents “no product”. (Null Object? null reference? Exception? You decide.) The rest of the way, we can assume that there is at least one row.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the first row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ask the Result Set (now pointing to the first row) for the values of the various columns and use that information to create a Product object.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the next row. If you find a next row, then throw an Exception communicating “We found too many rows, and that’s weird, because we thought we were finding rows by a primary key, and there should be just one matching row. The table in question is &lt;code&gt;products&lt;/code&gt;, which is probably missing a uniqueness constraint. Check the DDL. Good luck.” The rest of the way, we can assume that there is exactly one row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Now that we have our Product object, we need to clean up:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Close the Result Set, and if anything goes wrong, signal a warning about it, but keep going, because there’s nothing we can do about it now.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Close the Prepared Statement, and if anything goes wrong, signal a warning about it, but keep going, because there’s nothing we can do about it now.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Close the Connection, and if anything goes wrong, signal a warning about it, but keep going, because there’s nothing we can do about it now.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Return the Product as our final answer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Where there are multiple identical steps in succession, I can summarize the steps (hide the identical sections) to make the remaining differences stand out better.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transform the Data Source into a Prepared Statement.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tell the Prepared Statement about the query that you wish to execute:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;select * from products where products.id = ?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For the parameter placeholder, use the ID &lt;code&gt;17923&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Prepared Statement to execute the query, which returns a Result Set.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;We expect exactly one row, because our SQL statement filters on a primary key column, so if there is no row in the result set, then return an answer that represents “no product”. (Null Object? null reference? Exception? You decide.) The rest of the way, we can assume that there is at least one row.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the first row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ask the Result Set (now pointing to the first row) for the values of the various columns and use that information to create a Product object.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the next row. If you find a next row, then throw an Exception communicating “We found too many rows, and that’s weird, because we thought we were finding rows by a primary key, and there should be just one matching row. The table in question is &lt;code&gt;products&lt;/code&gt;, which is probably missing a uniqueness constraint. Check the DDL. Good luck.” The rest of the way, we can assume that there is exactly one row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Now that we have our Product object, &lt;strong&gt;clean up the opened resources&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Return the Product as our final answer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You’ll notice that in summarizing the identical steps, we have almost perfect alternation between identical steps and not-identical steps. This almost always happens, and so I interpret it as a sign that I have hidden the identical parts effectively.&lt;/p&gt;
&lt;h2 id=&quot;similar-parts-in-our-example&quot;&gt;Similar Parts in Our Example&lt;/h2&gt;
&lt;p&gt;Now I look at the similar parts, which would be identical if it weren’t for differences in data. I have highlighted the similarities and left the differences alone.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transform the Data Source into a Prepared Statement.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tell the Prepared Statement about the query that you wish to execute&lt;/em&gt;:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;select * from products where products.id = ?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For the parameter placeholder, use the ID &lt;code&gt;17923&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Prepared Statement to execute the query, which returns a Result Set.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;We expect exactly one row, because our SQL statement filters on a primary key column, so if there is no row in the result set, then return an answer that represents “no&lt;/em&gt; product&lt;em&gt;”. (Null Object? null reference? Exception? You decide.) The rest of the way, we can assume that there is at least one row.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the first row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ask the Result Set (now pointing to the first row) for the values of the various columns and use that information to create a&lt;/em&gt; Product &lt;em&gt;object&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the next row. If you find a next row, then throw an Exception communicating “We found too many rows, and that’s weird, because we thought we were finding rows by a primary key, and there should be just one matching row. The table in question is &lt;code&gt;products&lt;/code&gt;, which is probably missing a uniqueness constraint. Check the DDL. Good luck.” The rest of the way, we can assume that there is exactly one row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Now that we have our&lt;/em&gt; Product &lt;em&gt;object&lt;/em&gt;, &lt;strong&gt;clean up the opened resources&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Return the&lt;/em&gt; Product &lt;em&gt;as our final answer&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can summarize the differences this way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The SQL query text differs. (We’ll ignore for now the similarity in the structure of the SQL query.)&lt;/li&gt;
&lt;li&gt;The values of the SQL query parameter placeholders differ.&lt;/li&gt;
&lt;li&gt;The type of domain object we’re looking for differs.&lt;/li&gt;
&lt;li&gt;The way that we turn a Result Set row into a domain object differs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice that I could summarize the differences without making a reference to the concrete differences themselves. (I never wrote “Product” or “product ID” or “the table &lt;code&gt;products&lt;/code&gt;”). This means that I understand the differences enough to be able to turn similar code into identical code.&lt;/p&gt;
&lt;h2 id=&quot;turning-similar-code-into-identical-code&quot;&gt;Turning Similar Code into Identical Code&lt;/h2&gt;
&lt;p&gt;If you have two blocks of code with differing values, then you can simply extract the values, leaving behind parameters, and that turns similar code into identical code.&lt;/p&gt;
&lt;p&gt;For the SQL query text, we can simply make that a parameter.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source and the text of an SQL query that describes a “find, expecting a single match” scenario.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tell the Prepared Statement about the query that you wish to execute&lt;/em&gt;:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;em&gt;Use the SQL query provided to this function as the prepared statement query text&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;For the parameter placeholder, use the ID &lt;code&gt;17923&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;…continue as before.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sometimes the differences don’t have exactly the same shape, but we can make them have the same shape by thinking of what they have in common. We do this with the SQL statement parameters, because perhaps the number and type of parameters changes from statement to statement. We can use the &lt;em&gt;universal trick&lt;/em&gt; of naming the values, then putting the names and values into a lookup table. This means changing the SQL query to use named parameter placeholders instead of positional parameter placeholders — and even that &lt;em&gt;really&lt;/em&gt; just makes the whole thing easier to understand and harder to get wrong.&lt;/p&gt;
&lt;p&gt;We change our query details from this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;select * from products where products.id = ?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;17923&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;to this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;select * from products where products.id = :product_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{ :product_id =&amp;gt; 17923 }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, the way we turn “find a single row query details” into a Prepared Statement is the same for any SQL query that expects to find a single row. We just have a few rules about “find a single row query details” —&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The &lt;em&gt;query text&lt;/em&gt; uses named placeholders for the parameters.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;query parameters&lt;/em&gt; has an entry for each placeholder, and the keys of the query parameters match the names of the placeholders in the query text. The types of the values of the query parameters match the expected types of the placeholders in the query text. (We probably want to document the expected types, since SQL doesn’t force us to declare them in the query text itself.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As long as we follow these rules, our “find a single row query” procedure will work as expected, and now we turn a similar step into an identical step.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source and an SQL Query Description that describes a “find a single row” query.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tell the Prepared Statement about the query that you wish to execute&lt;/em&gt;:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;em&gt;Use the SQL Query Description’s query text as the Prepared Statement’s query text.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;For each query parameter in the SQL Query Description, tell the Prepared Statement to bind the parameter value to the corresponding parameter name.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;…continue as before.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that the similar parts are identical, let’s mark them as identical.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source and an SQL Query Description that describes a “find a single row” query.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tell the Prepared Statement about the query that you wish to execute&lt;/strong&gt;:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Use the SQL Query Description’s query text as the Prepared Statement’s query text.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For each query parameter in the SQL Query Description, tell the Prepared Statement to bind the parameter value to the corresponding parameter name.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;…continue as before.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this case, since the differences were “only” data (and not code), we can tell the overall procedure to just ask for that data as incoming parameters.&lt;/p&gt;
&lt;p&gt;We can do the same thing for all the places where the overall procedure mentions the table name &lt;code&gt;products&lt;/code&gt; in its exception message. We can pass the table name separately as an incoming parameter, then put a placeholder &lt;code&gt;&amp;lt;table name&amp;gt;&lt;/code&gt; in the exception message. This turns similar code into identical code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ask the Result Set to advance to the next row. If you find a next row, then throw an Exception communicating “We found too many rows, and that’s weird, because we thought we were finding rows by a primary key, and there should be just one matching row. The table in question is &lt;code&gt;&amp;lt;table name&amp;gt;&lt;/code&gt;, which is probably missing a uniqueness constraint. Check the DDL. Good luck.” The rest of the way, we can assume that there is exactly one row.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What about differences in code?&lt;/p&gt;
&lt;h2 id=&quot;turning-different-code-into-identical-code&quot;&gt;Turning Different Code Into Identical Code&lt;/h2&gt;
&lt;p&gt;The most difficult step involves turning an SQL Result Set row into a Product… or Customer or Order or whatever, because those steps require fundamentally different code — or do they? We can use another &lt;em&gt;universal trick&lt;/em&gt; to turn code into data. You can thank John von Neumann for this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To turn different blocks of code into data, extract the blocks of code into a function with identical (or even similar) signatures, and then hide the differences until they’re all gone. What’s left is a &lt;em&gt;common interface&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the case of turning an SQL Result Set row into a Product, we have a bunch of code like this —&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;ResultSet row = ...;
final int id = row.getInt(&amp;quot;id&amp;quot;);
final String description = row.getString(&amp;quot;description&amp;quot;);
final int priceInCents = row.getInt(&amp;quot;price_in_cents&amp;quot;);
final int shippingWeightInKilograms = row.getInt(&amp;quot;weight_in_kg&amp;quot;);
...
Product product = new Product(id, description, priceInCents, shippingWeightInKilograms, ...);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and in the case of turning an SQL Result Set row into a Customer, we have a bunch of code like this —&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;ResultSet row = ...;
final int id = row.getInt(&amp;quot;id&amp;quot;);
final String firstName = row.getString(&amp;quot;first_name&amp;quot;);
final String lastName = row.getString(&amp;quot;last_name&amp;quot;);
final Date dateOfBirth = row.getDate(&amp;quot;date_of_birth&amp;quot;);
...
Customer customer = new Customer(id, firstName, lastName, dateOfBirth, ...);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Although these blocks of code look wildly different, they both turn a ResultSet into a Thing (where &lt;em&gt;thing&lt;/em&gt; is a highly technical term meaning “Something I’m not sure about”). In some languages (Java, C#, C++, Haskell) we can use a generic type placeholder, which we conventionally call &lt;code&gt;T&lt;/code&gt;. In other languages (which ones?) we either can’t do this or don’t have to, in which case we can use the universal type that many languages call &lt;code&gt;Object&lt;/code&gt;. (We used to have to do this in Java, remember? Just me?) With this, we can extract both of these blocks of code into functions of type&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public &amp;lt;T&amp;gt; T mapRow(ResultSet row) throws RowMappingException { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or, in the worst case&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public Object mapRow(ResultSet row) throws RowMappingException { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we do next depends on our programming language. Either we pass the function directly into our overall procedure as a parameter or we create an interface that declares this function as &lt;em&gt;abstract&lt;/em&gt; (not implemented) and pass an instance of that interface into our overall procedure as a parameter. In C# we might use a Delegate. In Java we might use a first-class Function or declare an interface called &lt;code&gt;RowMapping&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;interface SqlRowMapping&amp;lt;DomainObjectType&amp;gt; {
  DomainObjectType mapRow(ResultSet row) throws RowMappingException;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we know something about what &lt;code&gt;T&lt;/code&gt; represents, there’s no reason to call it &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;In some cases, you don’t know &lt;em&gt;anything&lt;/em&gt; about what &lt;code&gt;T&lt;/code&gt; represents, such as “a list of things”. In this case, a type signature of &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; seems entirely appropriate. Don’t just call type parameters &lt;code&gt;T&lt;/code&gt; in order to blindly follow something that looks like a convention. In type names, &lt;code&gt;T&lt;/code&gt; is not a convention; instead, &lt;strong&gt;it’s a worst-case scenario&lt;/strong&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Whew! Now we can pass our “thing that maps a Result Set row into a domain object” into our overall procedure, and turn different code into identical code!&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source, an SQL Query Description that describes a “find a single row” query, and a Transformation that turns an SQL row into a Domain Object whose type matches what the SQL Query Description expects to find.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the Transformation to turn the Result Set (now pointing to the first row) into a Domain Object.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;…continue as before.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, we change the domain object type in our overall procedure from &lt;code&gt;Product&lt;/code&gt; to “generic thing”. We do this either by using the ancestor object type in our language (&lt;code&gt;Object&lt;/code&gt;) or by using a type parameter (&lt;code&gt;T&lt;/code&gt;, which we rename immediately to &lt;code&gt;DomainObjectType&lt;/code&gt;). Now — at last — we have a single universal procedure, which is our workflow.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Start with a Data Source, an SQL Query Description that describes a “find a single row” query, and a Transformation that turns an SQL row into a Domain Object whose type matches what the SQL Query Description expects to find.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transform the Data Source into a Prepared Statement.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tell the Prepared Statement about the query that you wish to execute&lt;/strong&gt;:
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;strong&gt;Use the SQL Query Description’s query text as the Prepared Statement’s query text.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For each query parameter in the SQL Query Description, tell the Prepared Statement to bind the parameter value to the corresponding parameter name.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Prepared Statement to execute the query, which returns a Result Set.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;We expect exactly one row, because our SQL statement filters on a primary key column, so if there is no row in the result set, then return an answer that represents “no Domain Object thing”. (Null Object? null reference? Exception? You decide.) The rest of the way, we can assume that there is at least one row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the first row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the Transformation to turn the Result Set (now pointing to the first row) into a Domain Object.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask the Result Set to advance to the next row. If you find a next row, then throw an Exception communicating “We found too many rows, and that’s weird, because we thought we were finding rows by a primary key, and there should be just one matching row. The table in question is &lt;code&gt;&amp;lt;table name&amp;gt;&lt;/code&gt;, which is probably missing a uniqueness constraint. Check the DDL. Good luck.” The rest of the way, we can assume that there is exactly one row.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Now that we have our Domain Object, clean up the opened resources&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Return the Domain Object as our final answer.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This gives you the workflow. You can now extract this workflow into a separate library function in order to provide standard behavior for the parts that shouldn’t change, such as handling errors and cleaning up resources. To use this library function, you only need to specify the differences, which means that you can focus on the important parts of your SQL queries: the table, the columns, how to turn a generic SQL row into a Product, Customer, or Order. You can check these things much more easily in isolation with microtests, rather than forcing yourself to use a database for each of those tests. Most importantly, once you see the pattern in this kind of behavior, you’ll start noticing high-level patterns of behavior throughout your system, which leads to less copy/paste and fewer mistakes of the kind “Hey! Why didn’t you do it ‘the normal way’?!”&lt;/p&gt;
&lt;p&gt;That’s the point of Template Method or &lt;strong&gt;Extract Workflow&lt;/strong&gt;, as I like to call it.&lt;/p&gt;
&lt;h2 id=&quot;hey-wait-this-isnt-a-template-method&quot;&gt;Hey, Wait… This Isn’t a Template Method!&lt;/h2&gt;
&lt;p&gt;You caught me. It isn’t really a Template Method. I don’t mind. Fortunately, what I did is &lt;em&gt;isomorphic&lt;/em&gt; to a Template Method, which means that there is a mechanical, universal code transformation between Template Methods and Standard Workflows of the type that I’ve extracted.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Template Method pattern&lt;/strong&gt; assumes that you want to pull the common steps up into a superclass and push the different (abstract) steps down into a subclass. In such a design, you would have a class for our query that looks something like this —&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;abstract class FindOneItemQuery&amp;lt;DomainObjectType&amp;gt; {
  public FindOneItemQuery(String sqlQueryTextWithNamedPlaceholders, Map&amp;lt;String, ?&amp;gt; sqlQueryParametersByName, String tableName) {
    // assign parameters to fields
  }

  // Our overall procedure!
  // It returns &amp;quot;maybe a Domain Object&amp;quot;.
  // If anything low-level goes wrong, it throws a database-driver-neutral exception.
  public final Optional&amp;lt;DomainObjectType&amp;gt; executeOn(DataSource dataSource) throws DatabaseCommandException;

  public abstract DomainObjectType mapRow(ResultSet row) throws RowMappingException;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then you would subclass to provide only the details.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;class FindProductByIdQuery extends FindOneItemQuery&amp;lt;Product&amp;gt; {
  public FindProductByIdQuery(int productId) {
    super(
      &amp;quot;select * from products where product.id = :product_id&amp;quot;,
      Collections&amp;lt;String, Integer&amp;gt;.singletonMap(&amp;quot;product_id&amp;quot;, productId),
      &amp;quot;products&amp;quot;
    );
  }

  public Product mapRow(ResultSet row) throws RowMappingException {
    final int id = row.getInt(&amp;quot;id&amp;quot;);
    final String description = row.getString(&amp;quot;description&amp;quot;);
    final int priceInCents = row.getInt(&amp;quot;price_in_cents&amp;quot;);
    final int shippingWeightInKilograms = row.getInt(&amp;quot;weight_in_kg&amp;quot;);
    ...
    return new Product(...);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t like this option, because of the possibility that &lt;code&gt;FindProductByIdQuery&lt;/code&gt; becoming tightly coupled to details in &lt;code&gt;FindOneItemQuery&lt;/code&gt;, making it impossible to test &lt;code&gt;mapRow()&lt;/code&gt; without having to deploy this SQL query into the production database environment. No thanks! I would rather be able to create a &lt;code&gt;ResultSet&lt;/code&gt; (itself an interface!) in a test and, in the worst case, I have to carefully simulate &lt;code&gt;ResultSet&lt;/code&gt; (a pretty terrible interface!) in order to avoid integrating with my production JDBC driver.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;In an industrial-strength situation, I would not depend on &lt;code&gt;ResultSet&lt;/code&gt; directly, but instead use some kind of Narrowing API that I can implement with an Adapter to JDBC &lt;strong&gt;or&lt;/strong&gt; use a real database driver for an in-memory database system and restrict myself very carefully to only the exact SQL standard that both database drivers mutually support. Both carry risks and I can’t evaluate those risks in the abstract; I’d have to consider a concrete situation to make that decision.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id=&quot;one-more-universal-trick&quot;&gt;One More Universal Trick!&lt;/h2&gt;
&lt;p&gt;Fortunately, there is a universal transformation for turning every abstract class (the usual design of a Template Method) into a design that doesn’t require inheriting implementation.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Create an interface that the abstract class will collaborate with, ideally by injecting the collaborating interface into the abstract class’s constructor. (You know, passing it as a parameter.)&lt;/li&gt;
&lt;li&gt;Copy the abstract methods from the abstract class onto the interface.&lt;/li&gt;
&lt;li&gt;Implement each abstract method on the abstract class to delegate to the collaborating interface.&lt;/li&gt;
&lt;li&gt;Now that the abstract class is no longer abstract (all its methods have an implementation), stop marking the class as &lt;code&gt;abstract&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Clean up the (now) concrete class, removing references to fields that now belong in implementations of the collaborating interface. &lt;em&gt;The abstract class shouldn’t have cared about those details in the first place!&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Now, add variation by implementing the collaborating interface, rather than by subclassing the formerly-abstract class.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This design turns a Template Method into a Standard Workflow (concrete class) that collaborates with Varying Steps (interface). It &lt;a href=&quot;https://refactoring.com/catalog/replaceInheritanceWithDelegation.html&quot;&gt;replaces inheritance with delegation&lt;/a&gt;, which is almost always a good idea. A functional programmer would just design it that way, anyhow, since they easily pass functions into other functions as parameters. In modern (as of 2016) object-oriented languages, we can do this with &lt;em&gt;lambda expressions&lt;/em&gt; just like the cool kids do in their fancy functional programming languages. Damn kids.&lt;/p&gt;
&lt;h2 id=&quot;one-more-thing&quot;&gt;One More Thing!&lt;/h2&gt;
&lt;p&gt;Functional programmers do a lot of &lt;a href=&quot;https://martinfowler.com/articles/collection-pipeline/&quot; title=&quot;This provides an example of this style of programming for operating on collections, where I find it particularly pleasing and convenient.&quot;&gt;Pipeline Programming&lt;/a&gt;. This means that they create a bunch of functions that each take a single argument and return a single value, then compose those functions together to build wonderful, complicated algorithms in which they have total confidence. The languages usually have &lt;a href=&quot;https://pragprog.com/magazines/2013-07/programming-elixir&quot; title=&quot;This article shows a really nice example of how to use the pipeline operator.&quot;&gt;some nice chaining operator to make the syntax really pretty&lt;/a&gt;. This makes it possible to write things like —&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def find_one_query(data_source, sql_query_description, map_row) {
  return data_source
    |&amp;gt; get_connection
    |&amp;gt; get_statement
    |&amp;gt; bind_statement(sql_query_description)
    |&amp;gt; execute_find_one_query
    |&amp;gt; map_row
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Syntax approximate. No warranty is provided nor implied. Do not try to compile.)&lt;/p&gt;
&lt;p&gt;Here, &lt;code&gt;bind_statement&lt;/code&gt; takes the output from &lt;code&gt;get_statement&lt;/code&gt; and combines it with the &lt;code&gt;sql_query_description&lt;/code&gt;, putting the SQL query text in the right place and binding the parameters to their respective placeholders. It answers the Prepared Statement, ready to be executed. Then &lt;code&gt;execute_find_one_query&lt;/code&gt; executes the statement, expecting a single row, the returning it. Finally, &lt;code&gt;map_row&lt;/code&gt; turns the generic row into a domain object (or &lt;code&gt;Nothing&lt;/code&gt;, if there’s no row to transform or something has gone wrong somewhere). I like this syntax, because it lets me see at a glance that the overall procedure is probably correct. If the types line up, then it will probably work. I like this about functional programming.&lt;/p&gt;
&lt;p&gt;In a language like Haskell, I guess you’d write it as function composition — and by “guess” I mean “this probably isn’t valid Haskell, but you get the idea”.&lt;/p&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;-- sql_query_description contains query text and query parameters
-- map_row : SqlRow -&amp;gt; DomainObject
-- data_source comes from the SQL library
find_one_query sql_query_description map_row data_source =
    (map_row
        . execute_find_one_query
        . (bind_statement sql_query_description)
        . get_statement
        . get_connection) data_source&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we could use eta conversion to avoid specifying the last parameter, &lt;code&gt;data_source&lt;/code&gt;, but I wanted to make the example a little clearer to people like me who only know enough functional programming concepts to be dangerous. I probably could have designed this better. Feel free to suggest improvements! I notice some similarities in the syntax, anyway.&lt;/p&gt;
&lt;h3 id=&quot;tangent-much&quot;&gt;Tangent Much?&lt;/h3&gt;
&lt;p&gt;Oh, yes! My point… &lt;strong&gt;a Pipeline is just a special kind of Standard Workflow (or Template Method) where each step sends its output into the next step as input&lt;/strong&gt;. So there’s nothing special or weird about a Pipeline, and it’s nothing particularly advanced or scary, and so you should just try designing with them and see what happens. No monads, even! (OK, maybe a monad, but it’ll be fine.)&lt;/p&gt;
&lt;h2 id=&quot;try-this-at-work&quot;&gt;Try This At Work!&lt;/h2&gt;
&lt;p&gt;Are you working on an application with a typical user interface? Web? Desktop? CLI? Doesn’t matter. I bet you that you have some Controllers with a Standard Workflow:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Validate parameters from the Request, replying with a Failure Response View if the parameters are invalid.&lt;/li&gt;
&lt;li&gt;Assuming that the Request is now worth processing, handle the Request, querying/updating the Model, then choosing a Response View.&lt;/li&gt;
&lt;li&gt;Render the Response View by combining it with data from the Model or the original Request.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Extract that workflow! Now you have standard error handling, logging, auditing, authentication, authorization, all that wonderful stuff. (OK… you’ll have it &lt;em&gt;eventually&lt;/em&gt;.) Where can you use these workflows in other parts of your system? What are the 3-5 Standard Workflows in your entire system? (There are probably only 3-5.) How do those Standard Workflows build on each other? Combine this with &lt;a href=&quot;#references&quot;&gt;pushing details up the call stack&lt;/a&gt; and look at how easy it becomes to do two important things —&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Check the details of the steps without having to run the Standard Workflows that you already know work!&lt;/li&gt;
&lt;li&gt;Replace a simpler Standard Workflow with a more complicated Standard Workflow when things change. Changing authentication providers, for example, should be easy.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Maybe you can find some other Standard Workflows in your system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Putting messages onto your messaging bus, dealing with MQ/JMS noise.&lt;/li&gt;
&lt;li&gt;Sending email, dealing with SMTP noise.&lt;/li&gt;
&lt;li&gt;Parse-Process-Format, such as what SOAP or other similar libraries are &lt;em&gt;supposed&lt;/em&gt; to do for you.&lt;/li&gt;
&lt;li&gt;REST something something, I don’t know. Almost certainly there, too.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/1Sb2djy&quot;&gt;“Demystifying the Dependency Inversion Principle”&lt;/a&gt;. The parts about dependency injection containers are the most relevant in this situation.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/2d0p0GB&quot;&gt;“Refactor Your Way to a Dependency Injection Container”&lt;/a&gt;. You don’t have to run screaming from dependency injection containers, but you &lt;em&gt;do&lt;/em&gt; need to understand what such a container is actually supposed to be doing.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/2dDCqqa&quot;&gt;“How Reuse Happens”&lt;/a&gt;. This whole article is an example of how reuse happens: you have to practise extracting similarities and you have to learn how to see past the differences to the deeper similarities.&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Oct 2016 08:37:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/no-more-boilerplate-code</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/no-more-boilerplate-code</guid>
        
        
        <category>Simple Design</category>
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>How Not To Write Golden Master Tests</title>
        <description>&lt;p&gt;I recently encountered a code base in which someone had applied the Golden Master technique, but done so in a way I find risky, so I wanted to warn you against letting this happen in your code. This code exhibits a bad idea that probably started out as a good idea or seemed like a good idea at the time. This makes it plausible-but-risky, and this is where a lot of legacy code comes from.&lt;/p&gt;
&lt;p&gt;The golden master tests are designed as JUnit tests, &lt;strong&gt;which I like very much&lt;/strong&gt;, because that should make it easier to simply run the tests while I’m programming. I tend to favor design decisions that encourage programmers to run more tests more easily, since that tends to encourage them to run more tests more often, and that mitigates some of the key risks associated with changing code. Unfortunately, following this principle led to a rather risky decision, which defeats the very purpose of &lt;em&gt;automated&lt;/em&gt; testing.&lt;/p&gt;
&lt;h2 id=&quot;the-dance-of-the-annotations&quot;&gt;The Dance of the Annotations&lt;/h2&gt;
&lt;p&gt;I’ll simply outline the structure of the test class. Do you notice the same design risk that I do?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class GoldenMasterTests {
  //@Test
  public void generate_golden_master() {
    WriteToFile(&amp;quot;master.txt&amp;quot;);
  }

  @Test
  public void compare_to_golden_master()
  throws IOException {
    WriteToFile(&amp;quot;test-run.txt&amp;quot;);
    String master = readFile(&amp;quot;master.txt&amp;quot;);
    String tests = readFile(&amp;quot;test-run.txt&amp;quot;);
    assertEquals(tests, master);
  }

  // irrelevant code omitted...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The commented-out &lt;code&gt;@Test&lt;/code&gt; annotation makes me nervous.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; This means that a programmer needs to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Switch annotations in order to run “generate golden master” when the golden master needs to change.&lt;/li&gt;
&lt;li&gt;Run all the tests—or worse, choose to run a single test just this once—in order to generate a new golden master.&lt;/li&gt;
&lt;li&gt;Remember to switch the annotations back in order to check the test run, which I &lt;em&gt;assume&lt;/em&gt; one would want this code to do by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This might not seem like a big deal, but &lt;strong&gt;legacy code is the result of hundreds (or thousands or more) of decisions like these, none of which seemed like a big deal&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;automating-the-automated-tests&quot;&gt;Automating the “Automated” Tests&lt;/h2&gt;
&lt;p&gt;If you don’t want to automate your test runs, then don’t use JUnit; if you want to use JUnit, then &lt;em&gt;automate your test runs&lt;/em&gt;. This means &lt;strong&gt;ruthlessly eliminating manual steps&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;One simple tactic comes to mind: let the test case class operate as both a collection of JUnit tests and as a standalone program (with &lt;code&gt;main()&lt;/code&gt;). Running the program creates a new golden master, while running the tests with JUnit compares the current test run to the latest version of the golden master. &lt;strong&gt;This follows the principle of automating the most-common task.&lt;/strong&gt;&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; Generating a golden master happens separately from running tests, so I see no benefit in using a JUnit test runner to do it. On the contrary, &lt;strong&gt;the design as it is now merely uses the JUnit test runner as a console application entry point&lt;/strong&gt;. Java already has &lt;code&gt;main()&lt;/code&gt;. I find it easier to understand than using the JUnit test runner somewhat like &lt;code&gt;main()&lt;/code&gt;. I especially find it strange to use the JUnit test runner to do something that isn’t running a test. So I propose we just use &lt;code&gt;main()&lt;/code&gt;!&lt;/p&gt;
&lt;h2 id=&quot;the-result&quot;&gt;The Result&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public class GoldenMasterTests {
  public static void main(String[] args)
  throws Exception {
    // irrelevant code omitted...
    writeTestRun(&amp;quot;master.txt&amp;quot;);
  }

  @Test
  public void compareToGoldenMaster()
  throws IOException {
    writeTestRun(&amp;quot;test-run.txt&amp;quot;);
    assertEquals(
      readTextFile(&amp;quot;master.txt&amp;quot;),
      readTextFile(&amp;quot;test-run.txt&amp;quot;));
  }

  // irrelevant code omitted...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this design, when you need to generate a new version of the golden master, you have to know to run &lt;code&gt;main()&lt;/code&gt;, but when you’re merely running the tests again, there’s no risk of accidentally generating a new, &lt;em&gt;possibly wrong&lt;/em&gt;, golden master.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Not all testing-related code needs to be designed as a test. Not all testing-related tasks involve running tests. Don’t trap yourself into thinking that you have to perform those tasks with your testing tools.
&lt;/p&gt;
&lt;h2 id=&quot;reaction&quot;&gt;Reaction&lt;/h2&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-cards=&quot;hidden&quot; data-lang=&quot;en&quot;&gt;
&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
How Not To Write Golden Master Tests by &lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;JBrains&quot;&gt;@JBrains&lt;/span&gt;&lt;/a&gt; &lt;a href=&quot;https://t.co/bJP1okwzxY&quot;&gt;https://t.co/bJP1okwzxY&lt;/a&gt; Suggested solution is inferior to Approvals &lt;a href=&quot;https://t.co/yK06QGDwtE&quot;&gt;https://t.co/yK06QGDwtE&lt;/a&gt; &lt;a href=&quot;https://t.co/fNzmvAH2Pu&quot;&gt;pic.twitter.com/fNzmvAH2Pu&lt;/a&gt;
&lt;/p&gt;
— roesslerj (&lt;span class=&quot;citation&quot; data-cites=&quot;roesslerj&quot;&gt;@roesslerj&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/roesslerj/status/898806239924113408&quot;&gt;August 19, 2017&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;It’s true, if you use a tool like &lt;a href=&quot;https://approvaltests.com/&quot;&gt;Approval Tests&lt;/a&gt;, then you get this behavior built in. That’s the point of any tool. In particular, it appears to help organize Golden Master tests in text files, associating them with xUnit tests in a way that I typically end up needing eventually. In cases where it’s especially convenient to express the expected result of a test in text, this tool makes that easier to do.&lt;/p&gt;
&lt;p&gt;So why didn’t I recommend it in the first place? I didn’t write this article to propose an ideal solution to this problem, nor to advertise a tool, but rather to point out &lt;em&gt;insufficient&lt;/em&gt; or &lt;em&gt;dangerous&lt;/em&gt; practice (in my opinion, of course) and describe a quick way to improve it. If you’re doing what I describe in this article in your project, then &lt;em&gt;stop&lt;/em&gt;, do something better &lt;em&gt;now&lt;/em&gt; with the tools at your disposal, and &lt;em&gt;then&lt;/em&gt; look for an even better way. That better way might be Approval Tests.&lt;/p&gt;
&lt;p&gt;Of course, don’t just reach for a tool to solve your problems. Don’t fall prey to the “Evil Wizard” problem, where a tool works like magic and you don’t know how to live without it. You don’t have to do everything “by hand”, but you should know how to. Accordingly, calling a manual solution “inferior” to an automated version of the same behavior build into a tool seems misguided. Instead I propose this:&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Good news, everyone! There are tools that do what I propose here, such as &lt;a href=&quot;https://approvaltests.com&quot;&gt;Approval Tests&lt;/a&gt;, so I recommend checking it out. It builds on the idea in this article and offers even more to help you organize and run your Golden Master tests.
&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;If you don’t know JUnit, the test runner runs methods annotated with &lt;code&gt;@Test&lt;/code&gt; as tests.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I don’t mind keeping, even adding, manual steps for &lt;em&gt;generating&lt;/em&gt; a golden master, since this adds a small measure of safety to a potentially destructive task.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Tue, 01 Mar 2016 12:30:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-not-to-write-golden-master-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-not-to-write-golden-master-tests</guid>
        
        
      </item>
    
      <item>
        <title>A Tiny Cohesion Risk</title>
        <description>&lt;p&gt;Today I’d like to share an example of a tiny cohesion risk. I leave it to you to evaluate the severity of the risk and the appropriateness of the refactoring. I like to deal with risks when they are small enough that their impact, while painful, probably won’t kill.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;//images.jbrains.ca/playful-tiger-cub.jpg&quot; alt=&quot;What a cute design risk!&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;What a cute design risk!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Let’s start with the code here:&lt;/p&gt;
&lt;pre data-caption=&quot;Write the subdomain redirect rules to files&quot;&gt;&lt;code&gt;patch_entries(simple_subdomain_redirect_rules,
  -&amp;gt;(k, v) { [k, SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)] })
.map { |k, v|
  File.open(File.expand_path(File.join(nginx_http_server_configuration_path, &amp;quot;redirect-#{k}.conf&amp;quot;)), &amp;quot;w&amp;quot;) do |f|
    f.write(v)
  end
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code writes an Nginx server block configuration of each of my &lt;em&gt;simple subdomain redirect rules&lt;/em&gt; to its own file. I’ve extracted the operation “patch entries” to its own function, which turns a Hash into a new Hash by transforming all the entries with the provided function.&lt;/p&gt;
&lt;aside&gt;
I need this because &lt;code&gt;map()&lt;/code&gt; turns a Hash into an Array of two-element Arrays, rather than into a new Hash.
&lt;/aside&gt;
&lt;p&gt;When I wrote this code, I thought of transforming the data this way.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Turn the subdomain redirect rules into an Array of Nginx server block configurations.&lt;/li&gt;
&lt;li&gt;Wait, no. I need a filename for each server block configuration. I’ll use the subdomain for part of the filename, so I need the original subdomain back. This means changing just the values of the Hash from target URL to server configuration block.&lt;/li&gt;
&lt;li&gt;Now that I have a mapping of subdomain to server configuration block, I can turn the subdomain into a file path to which to write the file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I thought of “generate Nginx server configuration block content” and “generate file path” as separate operations, so I arbitrarily put them in separate operations. Now that I’ve slept on it and come back to this code, I want to change that decision.&lt;/p&gt;
&lt;h2 id=&quot;judging-cohesion&quot;&gt;Judging Cohesion&lt;/h2&gt;
&lt;p&gt;I don’t mean judging the importance of cohesion, but rather what seems more cohesive. I see two alternatives.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Leave the code as it is, with file operations together, but separated from the &lt;em&gt;generate the Nginx server configuration block&lt;/em&gt; operation.&lt;/li&gt;
&lt;li&gt;Move the &lt;em&gt;generate filename&lt;/em&gt; operation together with the &lt;em&gt;generate the Nginx server configuration block&lt;/em&gt; operation in the first &lt;code&gt;map()&lt;/code&gt; call.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On the one hand, file operations together seem cohesive; on the other hand, it seems like generating a filename from a subdomain is quite specific to my current situation, whereas writing content to a file is very abstract, which I’d prefer to extract to its own function. Each options seems highly cohesive in its own way, so why does my intuition favor the second option over the first?&lt;/p&gt;
&lt;h2 id=&quot;dip-to-the-rescue&quot;&gt;DIP To the Rescue&lt;/h2&gt;
&lt;p&gt;Once again, the &lt;a href=&quot;#references&quot;&gt;dependency inversion principle&lt;/a&gt; helps break the apparent tie. In this case, it encourages me to move details up the call stack. “Write this stuff to a file” is quite generic, but “choose a filename &lt;em&gt;based on the subdomain&lt;/em&gt;” is quite detailed, so I move the latter up the call stack towards the client. This idea leads me to propose a new guideline.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
When in doubt, choose domain cohesion over layer cohesion.
&lt;/p&gt;
&lt;p&gt;In other words, gathering all the file-related operations in one place might help, but gathering all the domain concepts in one place might help more. I say “might”, because although it feels sensible, I haven’t done it enough to proclaim it confidently from the rooftops. I’ll have to try it out for a while and see what happens.&lt;/p&gt;
&lt;h2 id=&quot;the-resulting-code&quot;&gt;The Resulting Code&lt;/h2&gt;
&lt;pre data-caption=&quot;Domain cohesion over technology cohesion&quot;&gt;&lt;code&gt;patch_entries(simple_subdomain_redirect_rules,
  -&amp;gt;(k, v) {
    [File.expand_path(File.join(nginx_http_server_configuration_path, &amp;quot;redirect-#{k}.conf&amp;quot;)),
    SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)]})
.map { |k, v|
  File.open(k, &amp;quot;w&amp;quot;) do |f|
    f.write(v)
  end
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I can think of the data transformation more simply as &lt;em&gt;turn the subdomain rules into a dictionary mapping the filename to the content to write to the file&lt;/em&gt;. This version of the design “strips away the context” earlier, resulting in more generic code that’s easier to get right and smaller, more self-contained, reusable pieces that are easier to compose.&lt;/p&gt;
&lt;p&gt;For example, now I can clearly see value in extracting a function for “write this text to that file path”, making this code even easier to understand.&lt;/p&gt;
&lt;pre data-caption=&quot;Better isolated&quot;&gt;&lt;code&gt;# REUSE Text File library
def write_text_to_file(file_path, text)
  File.open(file_path, &amp;quot;w&amp;quot;) do |f|
    f.write(text)
  end
end

patch_entries(simple_subdomain_redirect_rules,
  -&amp;gt;(k, v) {
    [File.expand_path(File.join(nginx_http_server_configuration_path, &amp;quot;redirect-#{k}.conf&amp;quot;)),
    SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)]})
.map { |file_path, server_block_configuration_text|
  write_text_to_file(file_path, server_block_configuration_text)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that I’ve forced myself to articulate this previously-anonymous and detailed lambda, I search the web for “write text file ruby” and discover that this library function already exists. Of course it did! They use &lt;code&gt;File.write()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;patch_entries(simple_subdomain_redirect_rules,
  -&amp;gt;(k, v) {
    [File.expand_path(File.join(nginx_http_server_configuration_path, &amp;quot;redirect-#{k}.conf&amp;quot;)),
    SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)]})
.map { |file_path, server_block_configuration_text|
  File.write(file_path, server_block_configuration_text)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I would strongly prefer to use &lt;em&gt;eta-reduction&lt;/em&gt; on &lt;code&gt;File.write()&lt;/code&gt; and write something like &lt;code&gt;hash.map(File::write)&lt;/code&gt;, but that doesn’t seem to work the way I expect. If you can suggest how to write that block more concisely, &lt;a href=&quot;https://tell.jbrains.ca&quot;&gt;please tell me&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, if I want, I can extract the more-detailed code into little functions in order to make this chain of operations even clearer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# REUSE Library for higher-order functions
# REFACTOR Clojure calls this &amp;quot;juxt&amp;quot;
# and extends it to n functions with the same argument list
# NOTE argument lists must match among the functions!
# f : (args...) -&amp;gt; c
# g : (args...) -&amp;gt; d
# foo : (args...) -&amp;gt; [c, d]
def juxtapose_two_functions(f, g)
  -&amp;gt;(*args) { [f.(*args), g.(*args)] }
end

patch_entries(simple_subdomain_redirect_rules,
  juxtapose_two_functions(
    nginx_http_server_block_configuration_path_for(nginx_http_server_configuration_directory),
    nginx_http_server_block_configuration_for(nginx_servers_directory)
  )
).map { |file_path, server_block_configuration_text|
  File.write(file_path, server_block_configuration_text)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I feel in this case like “juxtapose two functions” takes away some of the clarity of the code, but that might reflect my unfamiliarity with the concept more than the name I’ve applied. At a minimum, most of the plumbing has disappeared into the background and we’re left with the following.&lt;/p&gt;
&lt;div class=&quot;explanation&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;Patch the “simple subdomain redirect rules” by replacing the keys with the Nginx HTTP server block configuration path for each subdomain and by replacing the values with the Nginx HTTP server block configuration based on where I’ve decided to put the Nginx servers. Then write each configuration to its file path. The end.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This sounds reasonable to me, at least if I give myself a chance to get used to “juxtapose two functions”. Maybe I can improve the name by calling it &lt;code&gt;patch_entry()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# REUSE Library for Hash or data structure operations.
# patch_key : (key -&amp;gt; value) -&amp;gt; new_key
# patch_value : (key -&amp;gt; value) -&amp;gt; new_value
def patch_entry_with(patch_key, patch_value)
  juxtapose_two_functions(patch_key, patch_value)
end

 patch_entries(simple_subdomain_redirect_rules,
  patch_entry_with(
    nginx_http_server_block_configuration_path_for(nginx_http_server_configuration_directory),
    nginx_http_server_block_configuration_for(nginx_servers_directory)
  )
).map { |file_path, server_block_configuration_text|
  File.write(file_path, server_block_configuration_text)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I prefer the way this code reveals its intent, and hides most of the plumbing. If I could pass &lt;code&gt;File.write()&lt;/code&gt; as a parameter directly to &lt;code&gt;Hash.map()&lt;/code&gt;, then that would eliminate the last bit of plumbing; however, Ruby doesn’t seem to allow that. (I’d have to convert the file path and content to a single argument, which I think would obscure the intent rather than reveal more of it.)&lt;/p&gt;
&lt;h2 id=&quot;more-reuse-clearer-intent-better-cohesion&quot;&gt;More Reuse! Clearer Intent! Better Cohesion!&lt;/h2&gt;
&lt;p&gt;In the process of improving the cohesion (I firmly believe) of this code, I have introduced some additional reusable, recombinable elements, including &lt;code&gt;juxtapose_two_functions()&lt;/code&gt; and &lt;code&gt;patch_entry()&lt;/code&gt;. I can even see how to extend &lt;code&gt;juxtapose_two_functions()&lt;/code&gt; into a general-purpose &lt;code&gt;juxtapose_functions()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I also find the intent easier to grasp, with the details safely hidden inside functions with intention-revealing names, like &lt;code&gt;patch_entry_with()&lt;/code&gt;, &lt;code&gt;nginx_http_server_block_configuration_path_for()&lt;/code&gt;, and &lt;code&gt;nginx_http_server_block_configuration_for()&lt;/code&gt;. Not only do the names better point to the related concepts, but the absence of details makes the key points stand out more prominently.&lt;/p&gt;
&lt;p&gt;In addition, the remaining code seems highly cohesive: it concentrates the Nginx-related code in one place, separating it from the generic Hash-related and File-related code. Similar things are closer together and different things are farther apart. Less risk of changing the wrong thing at the wrong time.&lt;/p&gt;
&lt;p&gt;Sometimes it only takes moving a single concept from one part of the code to another to start a chain reaction of refactorings that clarifies the whole thing, so &lt;strong&gt;don’t be afraid to set the timer for 30 minutes and just try refactoring!&lt;/strong&gt; In the worst case, after 30 minutes, you type&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git reset --hard HEAD
$ git clean --force&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and pretend it never happened.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;“Demystifying the Dependency Inversion Principle”&lt;/a&gt;. A place to start reading about the Dependency Inversion Principle. You can find more articles by &lt;a href=&quot;https://duckduckgo.com/?q=site%3Ablog.thecodewhisperer.com+dependency+inversion+principle&quot;&gt;clicking here&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 10 Feb 2016 11:58:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-tiny-cohesion-risk</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-tiny-cohesion-risk</guid>
        
        
      </item>
    
      <item>
        <title>How Reuse Happens</title>
        <description>&lt;p&gt;I often hear this: &lt;em&gt;Why should we extract this code? We only use it in one place. It doesn’t make sense to extract it.&lt;/em&gt; And yet, that same person wants to write tests for &lt;code&gt;private&lt;/code&gt; (or otherwise invisible) behavior. That person is only hurting themselves: they want to treat this code like a separate thing (because they want to test it), but they resist extracting it because “it doesn’t feel right”. I have safely extracted numerous mini-frameworks and mini-libraries and my only regret remains that I couldn’t easily have used someone else’s library for this in the first place. (How many times to we need to reimplement processing command line arguments? Mapping data from Java to SQL? Processing HTTP request headers? Hasn’t someone solved these already?)&lt;/p&gt;
&lt;p&gt;If you want reuse, you have to make it happen. Fortunately, you don’t need to be psychic; it’s enough to start by removing duplication, which makes opportunities for reuse easier to spot. Let me show you an example from code I’m working on to generate Nginx server block configurations I need to support some pretty URLs.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;Since I wrote this article, I have begun retiring my Typeform forms, so if there are any broken links here to a Typeform form, then that’s to be expected. Please don’t report those.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;I have some Typeform forms that I like to expose to the world with simpler addresses than Typeform generates by default. For example, if you want to ask me a question, you don’t visit &lt;a href=&quot;https://jbrains.typeform.com/to/RBZyN6&quot;&gt;https://jbrains.typeform.com/to/RBZyN6&lt;/a&gt; when you could instead simply go to &lt;a href=&quot;https://ask.jbrains.ca&quot;&gt;https://ask.jbrains.ca&lt;/a&gt;. I’m porting these redirect rules from Apache to Nginx and since I’m not under pressure to get it working &lt;em&gt;right now&lt;/em&gt;, I can take time to remove duplication. I’m using Erubis to generate the Nginx server block configurations from a template.&lt;/p&gt;
&lt;p&gt;When it came time to glue the pieces together, I reached the following code.&lt;/p&gt;
&lt;pre data-caption=&quot;generate_nginx_server_blocks_for_subdomain_redirects.rb&quot;&gt;&lt;code&gt;$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), &amp;quot;lib&amp;quot;)))

require &amp;#39;simple_subdomain_redirect&amp;#39;

nginx_http_server_configuration_path = ARGV[0] || &amp;quot;.&amp;quot;

simple_subdomain_typeform_redirect_rules = {
  &amp;quot;ask&amp;quot; =&amp;gt; &amp;quot;RBZyN6&amp;quot;,
  &amp;quot;tell&amp;quot; =&amp;gt; &amp;quot;dPumsI&amp;quot;,
  &amp;quot;sign-up&amp;quot; =&amp;gt; &amp;quot;rpvXwR&amp;quot;,
  &amp;quot;whatwouldthatgiveyou&amp;quot; =&amp;gt; &amp;quot;Z5URkO&amp;quot;,
  &amp;quot;book-training&amp;quot; =&amp;gt; &amp;quot;ljJ9Np&amp;quot;,
  &amp;quot;get-me-out-of-this-job&amp;quot; =&amp;gt; &amp;quot;xmQEzU&amp;quot;,
  &amp;quot;invite&amp;quot; =&amp;gt; &amp;quot;lwP9Kx&amp;quot;
}.map { |k, v|
  [&amp;quot;#{k}.jbrains.ca&amp;quot;, &amp;quot;https://jbrains.typeform.com/to/#{v}&amp;quot;]
}.to_h

# Collect all the rules here
simple_subdomain_redirect_rules = simple_subdomain_typeform_redirect_rules

simple_subdomain_redirect_rules.map { |k, v|
  [k, SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)]
}.to_h
.map { |k, v|
  File.open(File.expand_path(File.join(nginx_http_server_configuration_path, &amp;quot;redirect-#{k}.conf&amp;quot;)), &amp;quot;w&amp;quot;) do |f|
    f.write(v)
  end
}&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
Please ignore for now that this code &lt;a href=&quot;/permalink/relative-include-paths-and-the-slow-certain-march-towards-legacy-code&quot;&gt;fiddles directly with the Ruby load path&lt;/a&gt; and &lt;a href=&quot;https://github.com/ManageIQ/trollop&quot;&gt;very sloppily handles command-line parameters&lt;/a&gt;. I have those issues on my backlog; I’ll get to them.
&lt;/aside&gt;
&lt;p&gt;If you scan this code, you’ll notice some duplication. (Sure, there’s only two copies, but I can very clearly envision wanting to do this more than twice, and like I said, I have time to try this kind of thing.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &amp;quot;ask&amp;quot; =&amp;gt; &amp;quot;RBZyN6&amp;quot;,
  &amp;quot;tell&amp;quot; =&amp;gt; &amp;quot;dPumsI&amp;quot;,
  &amp;quot;sign-up&amp;quot; =&amp;gt; &amp;quot;rpvXwR&amp;quot;,
  &amp;quot;whatwouldthatgiveyou&amp;quot; =&amp;gt; &amp;quot;Z5URkO&amp;quot;,
  &amp;quot;book-training&amp;quot; =&amp;gt; &amp;quot;ljJ9Np&amp;quot;,
  &amp;quot;get-me-out-of-this-job&amp;quot; =&amp;gt; &amp;quot;xmQEzU&amp;quot;,
  &amp;quot;invite&amp;quot; =&amp;gt; &amp;quot;lwP9Kx&amp;quot;
}.map { |k, v|
  [&amp;quot;#{k}.jbrains.ca&amp;quot;, &amp;quot;https://jbrains.typeform.com/to/#{v}&amp;quot;]
}.to_h&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;simple_subdomain_redirect_rules.map { |k, v|
  [k, SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)]
}.to_h
.map { |k, v|
  File.open(File.expand_path(File.join(nginx_http_server_configuration_path, &amp;quot;redirect-#{k}.conf&amp;quot;)), &amp;quot;w&amp;quot;) do |f|
    f.write(v)
  end
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I notice the pattern of creating a Hash from another Hash by first converting to an Array of key-value pairs, then back to a Hash.&lt;/p&gt;
&lt;p&gt;I also notice that I’m doing this in order to apply some little transformation to each key-value pair—otherwise, why would I bother?&lt;/p&gt;
&lt;h2 id=&quot;what-changes-what-stays-the-same&quot;&gt;What Changes? What Stays the Same?&lt;/h2&gt;
&lt;p&gt;When I start to notice similarity in code, I look for what differs and what doesn’t, then look to separate the differences from the identical parts. In this case, we have a tiny Template Method:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;iterate over the Hash entries.&lt;/li&gt;
&lt;li&gt;transform the key and value into a two-element Array.&lt;/li&gt;
&lt;li&gt;collect the transformed entries into a new Array (of two-element Arrays).&lt;/li&gt;
&lt;li&gt;turn the Array back into a Hash.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As with any Template Method, the individual steps might differ, although the overall algorithm remains the same. In this specific case, the step “transform the key and value into a two-element Array” seems like a sensible point of variation. It seems reasonable to model this transformation as two one-argument functions, transforming the key and value respectively (and separately).&lt;/p&gt;
&lt;p&gt;Now, since “transform” is a very generic word, I look for a more concrete name for this operation. I don’t like it &lt;em&gt;much&lt;/em&gt; more, but I settle on “patch” for now. This leads me to want to extract a function called &lt;code&gt;patch_keys_and_values()&lt;/code&gt; that operates on a &lt;code&gt;Hash&lt;/code&gt; and takes two functions, the first one patches the keys and the second one patches the values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Turns hash into a new hash after applying patch_key() to each key
# and patch_value() to each value.
def patch_keys_and_values(hash, patch_key, patch_value)
  return hash.map { |k, v|
    patch_key.call(k), patch_value.call(v)
  }.to_h
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function is very abstract; it cares nothing at all about the details of the keys, values, or the hash. I mark its reuse level with a comment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# REUSE Library for Hash or data structure operations.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This seems so abstract, generic, and reusable that surely someone has thought of this and implemented it before, so I ask the Ruby community whether something like this already exists. If not, then I simply wait until I have a handful of similar functions, then extract them to a library and release it as a gem. Of course, I’d better test it really well.&lt;/p&gt;
&lt;h2 id=&quot;premature-generalization&quot;&gt;Premature Generalization?&lt;/h2&gt;
&lt;p&gt;Sadly, I can’t use this function for the second copy of the pattern, since its “new value” combines information from both the old key and the old value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;simple_subdomain_redirect_rules.map { |k, v|
  [k, SimpleSubdomainRedirect.new(k, v).to_nginx_server_block_configuration(&amp;quot;/home/nginx/servers&amp;quot;)]
}.to_h&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fortunately, although this changes the Template Method, it does so very little: it only changes the shape of the “transform” step. Actually… it doesn’t even do that; it merely violates a small design choice I made, namely to transform the key and value separately from one another with two different functions. I can easily change that to a single function that turns a key-value pair into another key-value pair without disturbing the Template Method. It amounts to a tiny change. For now, I extract a second function, to see how the two compare, rather than changing the first one.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# REUSE Library for Hash or data structure operations.
# Turns hash into a new hash after applying patch_entry()
# to each entry, returning a new key, value pair.
# patch_entry : (key -&amp;gt; value) -&amp;gt; [new_key, new_value]
def patch_entries(hash, patch_entry)
  hash.map { |k, v| patch_entry.call(k, v) }.to_h
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This shows the same level of reuse as the other function, so these two would go together in a new library.&lt;/p&gt;
&lt;p&gt;I briefly consider destroying the transform-the-key-and-value-separately version and use the transform-the-key-value-pair-together version for both cases. I can see value in both, so I keep them both until the more specific one starts to annoy me.&lt;/p&gt;
&lt;h2 id=&quot;avoiding-duplication&quot;&gt;Avoiding Duplication&lt;/h2&gt;
&lt;p&gt;I can also find some potentially-reusable stuff just by imagining duplication and extracting it.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; This means avoiding duplication, rather than removing it. I consider this riskier, because it leads to potentially premature optimization, but I can justify it (somewhat) on the grounds of improving names. The anonymous functions here stand out, because I can see their intent (for the moment, it’s fresh in my mind), but the code doesn’t express that intent.&lt;/p&gt;
&lt;aside&gt;
Some anonymous functions express their intent quite clearly, such as something like &lt;code&gt;-&amp;gt;(person) { person.age }&lt;/code&gt;, so not having a name, on its own, doesn’t always present a problem, nor even much of a risk.
&lt;/aside&gt;
&lt;pre&gt;&lt;code&gt;simple_subdomain_typeform_redirect_rules = patch_values_and_keys({
  &amp;quot;ask&amp;quot; =&amp;gt; &amp;quot;RBZyN6&amp;quot;,
  &amp;quot;tell&amp;quot; =&amp;gt; &amp;quot;dPumsI&amp;quot;,
  &amp;quot;sign-up&amp;quot; =&amp;gt; &amp;quot;rpvXwR&amp;quot;,
  &amp;quot;whatwouldthatgiveyou&amp;quot; =&amp;gt; &amp;quot;Z5URkO&amp;quot;,
  &amp;quot;book-training&amp;quot; =&amp;gt; &amp;quot;ljJ9Np&amp;quot;,
  &amp;quot;get-me-out-of-this-job&amp;quot; =&amp;gt; &amp;quot;xmQEzU&amp;quot;,
  &amp;quot;invite&amp;quot; =&amp;gt; &amp;quot;lwP9Kx&amp;quot;
}, -&amp;gt;(k) {&amp;quot;#{k}.jbrains.ca&amp;quot;}, -&amp;gt;(v) {&amp;quot;https://jbrains.typeform.com/to/#{v}&amp;quot;})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that I’ve got some of the plumbing out of the way, I can see the “patch key” and “patch value” functions more clearly. I see that in this case, for “patch key” I really want to “resolve the subdomain within the domain &lt;code&gt;jbrains.ca&lt;/code&gt;” and for “patch value”, I really want to “resolve the Typeform form URL for Typeform user &lt;code&gt;jbrains&lt;/code&gt;”. To give these ideas names, I move them into named functions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def resolve_jbrains_subdomain(subdomain)
  &amp;quot;#{subdomain}.jbrains.ca&amp;quot;
end

def jbrains_typeform_url(form_id)
  &amp;quot;https://jbrains.typeform.com/to/#{form_id}&amp;quot;
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don’t stop here! I can make these functions reusable by avoiding duplication (really removing latent duplication) and removing the dependency on the detailed values &lt;code&gt;jbrains.ca&lt;/code&gt; and &lt;code&gt;jbrains&lt;/code&gt;, respectively. (When I extract cohesive details like this—both values are related to &lt;code&gt;jbrains&lt;/code&gt;—I feel like I’ve got on a good track.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# REUSE HTTP/DNS library
def resolve_subdomain(domain)
  -&amp;gt;(subdomain) {
    &amp;quot;#{subdomain}.#{domain}&amp;quot;
  }
end

# REUSE Typeform integration library
def typeform_url(user_id)
  -&amp;gt;(form_id) {
    &amp;quot;https://#{user_id}.typeform.com/to/#{form_id}&amp;quot;
  }
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I like writing them this way to make it clearer that I intend to use them as factories for the functions that I’ll pass to &lt;code&gt;patch_keys_and_values()&lt;/code&gt;, but I think of them as two-argument functions that I intend to curry in order to pass to &lt;code&gt;patch_keys_and_values()&lt;/code&gt; as one-argument functions. At a minimum, I’ve clarified the intent of the client of this code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;simple_subdomain_typeform_redirect_rules = patch_values_and_keys({
    &amp;quot;ask&amp;quot; =&amp;gt; &amp;quot;RBZyN6&amp;quot;,
    &amp;quot;tell&amp;quot; =&amp;gt; &amp;quot;dPumsI&amp;quot;,
    &amp;quot;sign-up&amp;quot; =&amp;gt; &amp;quot;rpvXwR&amp;quot;,
    &amp;quot;whatwouldthatgiveyou&amp;quot; =&amp;gt; &amp;quot;Z5URkO&amp;quot;,
    &amp;quot;book-training&amp;quot; =&amp;gt; &amp;quot;ljJ9Np&amp;quot;,
    &amp;quot;get-me-out-of-this-job&amp;quot; =&amp;gt; &amp;quot;xmQEzU&amp;quot;,
    &amp;quot;invite&amp;quot; =&amp;gt; &amp;quot;lwP9Kx&amp;quot;
  },
  resolve_subdomain(&amp;quot;jbrains.ca&amp;quot;),
  typeform_url(&amp;quot;jbrains&amp;quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I couldn’t quickly figure out how to curry the two-argument functions in Ruby, so I asked Twitter, then moved on. (Currying lambdas? Easy. Currying Proc objects? Easy. Currying named functions? Not so much. &lt;a href=&quot;https://tell.jbrains.ca&quot;&gt;Do you know how to do it?&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id=&quot;reuse-opportunities-abound&quot;&gt;Reuse Opportunities Abound!&lt;/h2&gt;
&lt;p&gt;So in just this little bit of code I’ve extracted four bits of reusable code, three of which (I argue) are quite widely-reusable and the fourth of which (the Typeform one) perhaps has narrower potential for reuse. Even so, we don’t get reuse if we don’t look for potentially-reusable code and take one or two extra steps to make it reusable.&lt;/p&gt;
&lt;p&gt;Of course, you don’t need clairvoyance. Simply follow the &lt;a href=&quot;#references&quot;&gt;Simple Design Dynamo&lt;/a&gt; and look either for duplication or for code that combines details from too many concepts at once (seemingly-unrelated names close together), then separate the families of concepts from each other. In my case, I saw:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Duplication in the pattern of &lt;code&gt;hash.map { |k, v| [...make new key.., ...make new value...] }.to_h&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Different details too close together: pasting together subdomain and domain close to turning a Typeform form ID into the form URL.&lt;/li&gt;
&lt;li&gt;The detailed part of those two details (&lt;code&gt;jbrains.ca&lt;/code&gt; and &lt;code&gt;jbrains&lt;/code&gt;) happen to be quite similar, and so it might be nice to put them together somehow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can think of the second of these as potential duplication: at some point, it might be nice not to assume that the domain is &lt;code&gt;jbrains.ca&lt;/code&gt; and that the Typeform form URL starts with &lt;code&gt;jbrains.typeform.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Looking at the resulting code, all the data relates to the details of “jbrains”-ness: the redirect rules, the fact that my domain is &lt;code&gt;jbrains.ca&lt;/code&gt;, and the fact that my Typeform user ID is &lt;code&gt;jbrains&lt;/code&gt;. All the generic details, like resolving subdomains in a domain and resolve the URL of a Typeform form (in general), are hidden in code. This illustrates the &lt;a href=&quot;#references&quot;&gt;Pragmatic Programmer&lt;/a&gt; principle “Abstractions in code; details in metadata”, and provides yet another example of how following the Simple Design Dynamo can nudge the programmer towards a higher-level, well-respected, generally-helpful design principle.&lt;/p&gt;
&lt;p&gt;Nice, no?&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;“Putting An Age-Old Battle To Rest”&lt;/a&gt;. A description of the Simple Design Dynamo, which builds on Kent Beck’s pioneering description of the Four Elements of Simple Design.&lt;/p&gt;
&lt;p&gt;Andrew Hunt and Dave Thomas, &lt;a href=&quot;https://link.jbrains.ca/WNg8Se&quot;&gt;&lt;em&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/em&gt;&lt;/a&gt;. Still one of those classics that demands a place on every programmer’s bookshelf.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I would call this &lt;em&gt;advanced&lt;/em&gt; or &lt;em&gt;experienced&lt;/em&gt; practice. Generally, I recommend against speculating too much about duplication, waiting for three copies to happen, and if you and I were pairing, and you insisted that we not do this, I wouldn’t fight you for more than a few seconds this time.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 04 Feb 2016 11:45:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-reuse-happens</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-reuse-happens</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>How a Smell in the Tests Points to a Risk in the Design</title>
        <description>&lt;p&gt;In &lt;a href=&quot;https://blog.jenkster.com/2015/12/what-is-functional-programming.html&quot;&gt;“What Is Functional Programming?”&lt;/a&gt; I spotted a nice example of how duplication in tests leads to a suggestion to improve the design.&lt;/p&gt;
&lt;p&gt;Let’s start with his example function &lt;code&gt;getCurrentProgram()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Program getCurrentProgram(TVGuide guide, int channel) {
  Schedule schedule = guide.getSchedule(channel);
  Program current = schedule.programAt(new Date());
  return current;
}&lt;/code&gt;&lt;/pre&gt;
&lt;aside class=&quot;aside&quot;&gt;
&lt;p&gt;Notice, first of all, the word &lt;em&gt;current&lt;/em&gt;, which almost always reveals a risky, implicit dependency. The word “current” already suggests hardwiring the function to one particular instant in time, which is usually an arbitrary detail, and which is literally &lt;strong&gt;a detail that’s constantly changing&lt;/strong&gt;! It’s about as unstable a detail as one can have, and so depending on it seems awfully risky.&lt;/p&gt;
&lt;p&gt;Good news, though: even if you don’t react to the word “current”, you will almost certainly have trouble testing the function as is.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;As Kris Jenkins points out in his article, this function has a hardwired (difficult to change) implicit (unspoken) dependency on the current time. I find it no less difficult to use and significantly easier to test by simply making the hardwired implicit dependency both explicit and pluggable by turning it into a parameter. Making this change suggests to me to rename the function, since it no longer depends on the detail of “now” or “current”, and instead becomes “get program at/on/as of”.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Program getProgramAt(TVGuide guide, int channel, Date when) {
  Schedule schedule = guide.getSchedule(channel);
  Program program = schedule.programAt(when);
  return program;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As Kris points out, this version makes all its dependencies explicit and pluggable. This leads to a few benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To write a test, I can confidently determine the expected result from the inputs without having to look at the implementation for additional dependencies to set up.&lt;/li&gt;
&lt;li&gt;To write a test, I don’t have to resort to hijacking &lt;code&gt;new&lt;/code&gt;, because the concept of “where the date came from” is no longer inside the function. The function doesn’t care where the date came from.&lt;/li&gt;
&lt;li&gt;When I specify the inputs and expected results in the test, the link between them will be obvious, which makes it easier to figure out how to write more tests, later, after people have added more code and we’ve encountered a problem.&lt;/li&gt;
&lt;li&gt;We can reuse this code in other contexts! Kris offers the example that we get “What’s showing on channel 45 in an hour?” by simply passing the equivalent of &lt;code&gt;now + 1 hour&lt;/code&gt;. This is the power of context independence.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even so, I see a problem. Commenter Mario T. Lanza saw the problem even before I did.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I like your exposition and many excellent points; however, as a minor point, we should note that getProgramAt has a Law of Demeter violation that increases complexity. —Mario T. Lanza, &lt;a href=&quot;https://blog.jenkster.com/2015/12/what-is-functional-programming.html#comment-2432023201&quot;&gt;in a comment&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As soon as I saw the problem, I saw how it would affect the tests, and that’s what I wanted to write about here today.&lt;/p&gt;
&lt;h2 id=&quot;duplicate-irrelevant-details-in-the-tests&quot;&gt;Duplicate Irrelevant Details in the Tests&lt;/h2&gt;
&lt;p&gt;I first wrote about the power of irrelevant details in tests in 2010. (Read &lt;a href=&quot;/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;“What Your Tests Don’t Need To Know Will Hurt You”&lt;/a&gt;.) In the intervening time, I’ve discussed the idea a lot in my training classes, but never taken the time to write the details down, mostly for lack of good examples. Since I found a good example today, I decided to take the time to write about it today.&lt;/p&gt;
&lt;p&gt;Kris’ example leads to simpler, clearer tests once we parameterize the &lt;em&gt;instant&lt;/em&gt; at which we want to find the program airing on a specific channel. Even so, I notice a pattern in the tests the moment I start writing them.&lt;/p&gt;
&lt;div class=&quot;test-table&quot; data-markdown=&quot;1&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr class=&quot;header&quot;&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;guide&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;channel ID&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;when&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;expected program&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;45&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:00:00 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Breaking Bad S01E01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;45&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:29:59 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Breaking Bad S01E01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;45&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:30:00 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Better Call Saul S01E01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;45&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:59:59 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Better Call Saul S01E01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;45&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 13:00:00 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Breaking Bad S01E02&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;aside class=&quot;aside&quot;&gt;
&lt;p&gt;I’ve left out the details of how to describe the guide, but you can bet that somewhere in there is a piece of data that links channel 45 and noon on January 1, 2016 to Breaking Bad, season 1, episode 1 for the first two tests, then channel 45 and 12:30 to Better Call Saul, season 1, episode 1 for the next two tests, as well as channel 45 and 13:00 to Breaking Bad, season 1, episode 2 for the last test. I certainly hope that the tests don’t all use the same guide data.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Do you notice that the channel number is the same in every test? This makes me wonder whether the channel number provides any value to the test. Worse, imagine if I’d followed the time-honored heuristic of using different data for each test! In that case, the channel numbers would be different for each test, and I might not have noticed that the channel number looks like an irrelevant detail for the test!&lt;/p&gt;
&lt;p&gt;Irrelevant? How can it be? Surely we need the channel number in order to determine which show is on that channel at a given time!&lt;/p&gt;
&lt;p&gt;No, we don’t. The channel number is just a leaky implementation detail that forces us to understand how to look up a channel in a guide. It feels natural because we’ve collectively lived with channel numbers since the 1930s and if you’re reading this then you’ve probably never known a world without channel numbers… except Netflix, YouTube, Hulu, and the world of torrents. Moreover, the act of writing that in words has made the design risk even clearer, because it surfaces the intent behind the test: to be able to answer “what’s playing on this channel at a specific instant in time?” and not to answer “where does a channel’s schedule come from?”&lt;/p&gt;
&lt;p&gt;Why do we need to go to the “guide” to answer this question? &lt;em&gt;Why do we need to know the details of how to obtain the stream of shows on a channel when we’re only interested in finding the show scheduled to air at a specific instant?&lt;/em&gt; Why, indeed?&lt;/p&gt;
&lt;h2 id=&quot;rate-of-change-of-inputs&quot;&gt;Rate Of Change Of Inputs&lt;/h2&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;Cohesion seems to relate to how reasonably one could see the reasons for a module to change as a single reason.&quot;&gt;&lt;/span&gt; I like Bob Martin’s formulation of the Single Responsibility Principle: a module should have a single reason to change. Cohesion seems to relate to how reasonably one could see the reasons for a module to change as a single reason. I see the same principle at work in another context: I prefer to separate parameters that change values at different rates from each other. If I notice that 80% of the calls to a function pass the same value for a parameter, then I have the impulse to to elevate that parameter to the constructor of some class. Functional programming practitioners know this as currying or partially applying the function. (I still don’t quite understand the difference between these two things. Feel free to teach me.) It provides a natural way for values to flow through a design.
&lt;/p&gt;
&lt;h2 id=&quot;removing-the-duplicated-irrelevant-detail-from-the-tests&quot;&gt;Removing the Duplicated, Irrelevant Detail From the Tests&lt;/h2&gt;
&lt;p&gt;The repeated &lt;code&gt;45&lt;/code&gt; in my tests stand out against the background of the varying values in the &lt;strong&gt;guide&lt;/strong&gt; and &lt;strong&gt;when&lt;/strong&gt; columns. It’s as though the test wants the &lt;strong&gt;channel&lt;/strong&gt; column out of the way and is only providing a value for it because the design (for the moment) demands it. Even more telling, the only parts of the &lt;strong&gt;guide&lt;/strong&gt; that the tests cares about are the programs scheduled to air on channel 45.&lt;/p&gt;
&lt;p&gt;There’s a clue in that sentence.&lt;/p&gt;
&lt;p&gt;The test would rather simply check the program airing on a stream of programs organized by time. Fortunately, the current design already has a name for that: the &lt;code&gt;Schedule&lt;/code&gt;, meaning the schedule of programs on a specific channel. In that case, these tests really want to check &lt;code&gt;Schedule.programAt(when)&lt;/code&gt;, and so perhaps they should.&lt;/p&gt;
&lt;div class=&quot;test-table&quot; data-markdown=&quot;1&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr class=&quot;header&quot;&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;schedule&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;when&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;expected program&lt;/th&gt;
&lt;th style=&quot;text-align: center;&quot;&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:00:00 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Breaking Bad S01E01&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:29:59 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Breaking Bad S01E01&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:30:00 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Better Call Saul S01E01&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;even&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 12:59:59 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Better Call Saul S01E01&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;odd&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;{…}&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2016-01-01 13:00:00 -0300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Breaking Bad S01E02&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Better? Maybe. Simpler, at least. At a minimum, the tests no longer duplicate irrelevant details. Each test states simply “if the schedule contains program P airing in time range R, then when we ask it what’s airing at instant T in R, then it should return program P”. Direct. Less waste. Obvious. Almost too obvious.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When it seems too simple, then it’s finally simple enough.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;mechanical-or-intuitive&quot;&gt;Mechanical or Intuitive&lt;/h2&gt;
&lt;p&gt;I always feel more comfortable when multiple signals point me towards the same underlying design risk, because even on my worst days, I’m probably going to notice at least one of those signals. I categorize these signals as either &lt;em&gt;mechanical&lt;/em&gt; or &lt;em&gt;intuitive&lt;/em&gt;, depending on whether they rely on knowing lower-level rules (mechanical) or higher-level principles (intuitive). In this case, I see a bit of both. Specifically, I saw/felt/noticed these signals:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Repeating the channel number value in every test, and applied the &lt;em&gt;mechanical&lt;/em&gt; rule of “remove duplication”.&lt;/li&gt;
&lt;li&gt;The word “current” in the name of the function and immediately guessed (thanks to my &lt;em&gt;intuition&lt;/em&gt;) that it unnecessarily depended on a specific instant in time (namely &lt;em&gt;now&lt;/em&gt;, since that’s what “current” means).&lt;/li&gt;
&lt;li&gt;The combination of &lt;strong&gt;guide&lt;/strong&gt; and &lt;strong&gt;channel number&lt;/strong&gt; as a kind of repository lookup (&lt;em&gt;intuitive&lt;/em&gt;) being bound to a lookup within the result of the first lookup, and that usually spells trouble.&lt;/li&gt;
&lt;li&gt;The tests as is would probably lead to creating a &lt;strong&gt;guide&lt;/strong&gt; with either (1) only the data from a single &lt;strong&gt;schedule&lt;/strong&gt; in it, or (2) arbitrary data from other, irrelevant schedules/channels, just to avoid silly implementations like “assume channel 45 is the only channel we have”, which felt wrong (&lt;em&gt;intuition&lt;/em&gt;) and obscured the link between the inputs and the expected result (&lt;em&gt;mechanical&lt;/em&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Individually, maybe these signals don’t suffice to suggest a change, but taken together, they beat me into submission and I change the design to make the tests easier to express more directly. Even if I miss the intuitive signals, &lt;strong&gt;removing duplication of irrelevant details in the tests&lt;/strong&gt; usually points my designs in a healthy direction.&lt;/p&gt;
&lt;h2 id=&quot;one-last-thing&quot;&gt;One Last Thing&lt;/h2&gt;
&lt;p&gt;At best, &lt;code&gt;getProgramAt(guide, channel, when)&lt;/code&gt; works well as a convenience method for a specific application that presents the guide information to the TV viewer organized by numbered channels. Accordingly, this function makes perfect sense as a facade method integrating the user interface to the domain of the system. Even so, I’d prefer to call it &lt;code&gt;lookupProgramInGuideAt(guide, channel, when)&lt;/code&gt; to emphasize that we’re willing, just this once, to bind together the details of where a channel’s schedule comes from to looking up a program on that schedule. Moreover, I would really, really prefer to implement the function in a language with named parameters, like Smalltalk.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unnamedObject lookupProgramAt: (Date now) onChannel: 45 inGuide: guide&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Steve Freeman and Nat Pryce, &lt;a href=&quot;https://link.jbrains.ca/goos-book&quot;&gt;&lt;em&gt;Growing Object-Oriented Software Guided by Tests&lt;/em&gt;&lt;/a&gt;. Context independence. This book hammers you over the head with it. Enjoy.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;“What Your Tests Don’t Need To Know Will Hurt You”&lt;/a&gt;. An earlier, more generic, and frankly less clear version of this article.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/injecting-dependencies&quot;&gt;“Injecting Dependencies, Partially Applying Functions, and It Really Doesn’t Matter”&lt;/a&gt;. Tests don’t care whether they’re function parameters or fields on an object, so take advantage of the flexibility!&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.jbrains.ca/permalink/becoming-an-accomplished-software-designer&quot;&gt;“Becoming An Accomplished Software Designer”&lt;/a&gt;. An outline of how I have used TDD to develop what Michael Feathers calls “design sense”. It also explains why I teach modular design using TDD.&lt;/p&gt;
</description>
        <pubDate>Thu, 21 Jan 2016 11:30:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-a-smell-in-the-tests-points-to-a-risk-in-the-design</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-a-smell-in-the-tests-points-to-a-risk-in-the-design</guid>
        
        
      </item>
    
      <item>
        <title>Relative Include Paths and the Slow, Certain March Towards Legacy Code</title>
        <description>&lt;p&gt;When you use relative include paths in your code, you bind each source code file to its current location in the project’s file layout. You relegate yourself to having to run it from a very specific location on the file system. You generally make it unnecessarily difficult to automate running your application (or its tests) outside your development environment, such as in platform-as-a-service environments. You make things like Docker not just helpful, but &lt;em&gt;necessary&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So stop doing that.&lt;/p&gt;
&lt;p&gt;You can improve your code by following the Dependency Inversion Principle. Really! In particular, you can push a detail up the call stack towards the client. Which detail? &lt;strong&gt;Where to look for source code&lt;/strong&gt;. Pushing this detail up the call stack means pushing it out of your source code files and into the commands that run your code.&lt;/p&gt;
&lt;h2 id=&quot;why-do-your-tests-know-where-the-production-code-is&quot;&gt;Why Do Your Tests Know Where the Production Code Is?!!?&lt;/h2&gt;
&lt;p&gt;I can’t even.&lt;/p&gt;
&lt;p&gt;Yes: your tests need to &lt;em&gt;invoke&lt;/em&gt; your production code, but I don’t see the benefit from binding your tests to the current, arbitrary layout of your production code on the file system. When I’ve asked people why they’ve done it this way, they’ve answered one of two ways:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;“No reason.”&lt;/li&gt;
&lt;li&gt;“This is the only way it works.”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;They don’t know what else to do and they just need to get something running now, so that they can get on with it. So, as a result, we see things like—&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(in $PROJECT/spec/a/b/c/my_spec.rb)
include &amp;quot;../../../../lib/a/b/c/production_code&amp;quot;

# A bunch of delightful specs&lt;/code&gt;&lt;/pre&gt;
&lt;figure&gt;
&lt;img src=&quot;//images.jbrains.ca/disapproving-quincy-300w.jpg&quot; alt=&quot;Rly?!&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Rly?!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Your source code consists of a bunch of trees of files, with various roots. You might have one root for all your production code and one root each for various sets of tests, which you might want to run in isolation from each other. Every compiler and interpreter I’ve ever worked with has the concept of a “load path” (classpath, &lt;code&gt;PYTHONPATH&lt;/code&gt;, whatever they call it), which amounts to a collection of file paths where to search for source code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So use it&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;just-use-the-load-path&quot;&gt;Just Use The Load Path!&lt;/h2&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;Push knowledge about the location of your source code out of the source code (what an idea!) and into the commands that run your code.&quot;&gt;&lt;/span&gt; That’s it. It’s that easy. Push knowledge about the location of your source code out of the source code (what an idea!) and into the commands that run your code. Instead of obsessing over where to find other source code, your source files should just say “I need library X; I don’t care where it is, just let me use it”.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(in $PROJECT/spec/a/b/c/my_spec.rb)
# The production code is somewhere on this disk.
include &amp;quot;a/b/c/production_code&amp;quot;

# A bunch of delightful specs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can run this with a command like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ruby -Ispec/slow -Ispec/fast -Ilib -Ilegacy-lib my_awesome_entry_point.rb&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or whatever you call it in the language you’re using. It’s not difficult and it opens up options. You won’t realize how much you value those options until you’re able to actually take advantage of them. (“Oh. We’d love to use Awesome Tool X, but we can’t figure out how to deploy our legacy code into their environment.”)&lt;/p&gt;
&lt;h2 id=&quot;but-use-the-narrowest-scope-possible&quot;&gt;But Use The Narrowest Scope Possible&lt;/h2&gt;
&lt;p&gt;Just because you use a load path doesn’t give you licence to start using environment variables. (I’m looking at you, Python. At least you offer the &lt;code&gt;-E&lt;/code&gt; switch that I can use to ignore the environment variables while I figure out how to set the load path for just this command.) Srsly. Specify the load path when you run your code: your compiler or interpreter almost certainly has a way to specify the load path. If this results in a long command, then move that command into a script where you don’t have to see the details except when they change. (The shell scripting language is just a programming language. Don’t fear it. Buy a good book, dip your toe in at first, and it’ll be fine.) Now &lt;em&gt;you have the option to reorganize your source code&lt;/em&gt; when the need arises for a new level of organization. Such as when to move to a new runtime environment, like SaaS, PaaS, IaaS, or whatever the hell the kids are doing these days.&lt;/p&gt;
&lt;aside class=&quot;aside&quot;&gt;
Has anyone else noticed that this is really just a special kind of dependency injection? The commands that run the code inject the location of the source code trees into the source code.
&lt;/aside&gt;
&lt;h2 id=&quot;this-is-not-just-academic-bullshit&quot;&gt;This Is Not Just Academic Bullshit&lt;/h2&gt;
&lt;p&gt;Some of you have read this and thought something like: &lt;em&gt;J. B.’s gone off the deep end! He’s ranting about something that isn’t a problem. Everyone does it this way. I never want to change the relative layout of my source code. This is stupid.&lt;/em&gt; Guess what, folks: &lt;strong&gt;this attitude is how legacy code happens&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This attitude leads to “You have to follow these 7 arcane manual steps every alternate Friday (except holidays) in order for the app to run—&lt;em&gt;obviously&lt;/em&gt;!” Why would you volunteer to live in this world? &lt;strong&gt;Why do you insist on volunteering to live in this world?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Stop it. It’s so easy to stop it. Just stop it.&lt;/p&gt;
&lt;p&gt;Or don’t stop it. I don’t mind. I get paid the same amount either way. Actually—if you keep doing the easy, silly thing, then I get paid more, later. I have the stomach for it &lt;em&gt;and&lt;/em&gt; I know how to fix it.&lt;/p&gt;
&lt;h2 id=&quot;about-node.js&quot;&gt;About Node.js…&lt;/h2&gt;
&lt;p&gt;I tried writing something using Node.js and became immediately annoyed by the proliferation of relative include paths. At the time (September 2018) I couldn’t find a useful tutorial on how to build something like a load path for a Node project. I yelled into the void, hoping someone would send me some useful reference on the topic, and two years later (August 2020), one of you did. Thank you, Amith George!&lt;/p&gt;
&lt;p&gt;I haven’t read it in detail yet, because I’m not trying to build anything using Node.js right now, but I wanted to share it with you in case you found it useful.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/branneman/8048520#better-local-require-paths-for-nodejs&quot;&gt;“Better local require() paths for Node.js”&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;//blog.thecodewhisperer.com/2013/01/29/consequences-of-dependency-inversion-principle/&quot;&gt;“Demystifying the Dependency Inversion Principle”&lt;/a&gt;. A more detailed discussion of the Dependency Inversion Principle, including a section on moving implementation details up the call stack.&lt;/p&gt;
</description>
        <pubDate>Tue, 12 Jan 2016 09:30:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/relative-include-paths-and-the-slow-certain-march-towards-legacy-code</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/relative-include-paths-and-the-slow-certain-march-towards-legacy-code</guid>
        
        
        <category>Surviving Legacy Code</category>
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Clearing Up the Integrated Tests Scam</title>
        <description>&lt;p&gt;No matter what one writes, no matter how carefully one tries to articulate it, a non-trivial segment of the readership will interpret it differently from what one intended. So it has gone with &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;“Integrated Tests are a Scam”&lt;/a&gt;. I’d like to address some common differences of interpretation.&lt;/p&gt;
&lt;h2 id=&quot;integrated-not-integration&quot;&gt;“Integrated”, not “Integration”&lt;/h2&gt;
&lt;p&gt;This point might seem small, but it matters. Word matters. Meaning matters. In 2009 I presented “Integration Tests are a Scam” to an audience at the Agile (North America) conference in Chicago. At the time, I was still formulating the key ideas and fumbling around in the dark, confident that (what I called at the time) “integration tests” were creating more problems than they were solving. Either at that conference or shortly thereafter, I spoke with several people who told me that they disagreed with my use of the term “integration tests”, because they’d used the term to refer to what I was calling “collaboration tests”.&lt;/p&gt;
&lt;p&gt;It hit me like a ton of bricks. Of course! I’d got that wrong. An &lt;em&gt;integration&lt;/em&gt; test checks the integration between parts or layers of the system. I was telling people the equivalent of “collaboration tests are a scam, so use collaboration and contract tests instead”, which, when I write it this way, is obviously nonsense. It couldn’t possibly be what I meant.&lt;/p&gt;
&lt;aside class=&quot;aside&quot;&gt;
(You’d be surprised how many people seriously think that this is what I meant. I wish they would take the time to interpret more generously. That’s another article.)
&lt;/aside&gt;
&lt;p&gt;This explains why I began calling them &lt;em&gt;integrated tests&lt;/em&gt;, even making sure to distinguish the two terms when I presented “Les tests intégrés sont une arnaque!” at Agile Grenoble in 2011. There, at least one audience member seemed to understand the difference.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Je précise que Joe fait une différence entre tests d’intégration et tests intégrés qui sont pour lui des tests dont la réussite ou l’échec dépend de plusieurs parties intéressantes du système.&lt;/p&gt;
&lt;p class=&quot;translation&quot;&gt;
I mean that Joe distinguishes between integration tests and integrated tests, the latter of which are, for him, tests whose success or failure depends on several interesting parts of the system.
&lt;/p&gt;
&lt;p&gt;—Fabrice Aimetti, &lt;a href=&quot;https://www.fabrice-aimetti.fr/2011/11/25/retrospective-de-lagile-grenoble-2011/&quot;&gt;“Rétrospective de l’Agile Grenoble 2011”&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Knowing the confusion that I could have been causing, I made sure to change all my old articles—as many as I had the authority to change—and to start drawing attention to the fact that I had made a mistake saying “integration tests” when I meant “integrated tests”. Unfortunately, &lt;a href=&quot;https://infoq.com&quot;&gt;infoq.com&lt;/a&gt; posted video from the Agile 2009 presentation and many people just don’t take the time to think about the difference between the two terms, perpetuating the confusion.&lt;/p&gt;
&lt;p&gt;Even in late 2015 I woke up to a tweet claiming that I believe integration tests to be a scam. It has become a runaway train and I can’t stop it.&lt;/p&gt;
&lt;p&gt;So let me state it clearly: &lt;strong&gt;integrated tests, and not integration tests, are the scam&lt;/strong&gt;. They act like aspirin that makes the headache worse. The scam goes like this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;We have 100% passing tests, but we still have bugs.&lt;/li&gt;
&lt;li&gt;I know! Our “unit tests” don’t check how the system “hangs together”, so we need integrated tests to make sure that the “real things” work when we put them together!&lt;/li&gt;
&lt;li&gt;We write more integrated tests, which are bigger and don’t criticize our design as harshly as microtests do.&lt;/li&gt;
&lt;li&gt;Our tests don’t give us as quick nor strong feedback about our design as they could, and we’re humans, so we design things less carefully than we could. We design more sloppily both because we can get away with it and because we don’t notice as easily that it’s happening.&lt;/li&gt;
&lt;li&gt;Our designs become more interdependent, tangled, and generally impenetrable.&lt;/li&gt;
&lt;li&gt;The more interdependent our designs become, the harder it becomes to write good microtests.&lt;/li&gt;
&lt;li&gt;We write fewer microtests.&lt;/li&gt;
&lt;li&gt;The probability of 100% passing tests, but we still have bugs, &lt;strong&gt;increases&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Repeat until project heat death. (This is the point where starting over is cheaper than continuing with this code base.)&lt;/p&gt;
&lt;p&gt;You can yell “straw man” all you want. I see it happen.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
Strong &lt;strong&gt;integration tests&lt;/strong&gt;, consisting of &lt;strong&gt;collaboration tests&lt;/strong&gt; (clients using test doubles in place of collaborating services) and &lt;strong&gt;contract tests&lt;/strong&gt; (showing that service implementations correctly behave the way clients expect) can provide the same level of confidence as &lt;strong&gt;integrated tests&lt;/strong&gt; at a lower total cost of maintenance.
&lt;/p&gt;
&lt;p&gt;This last paragraph is the key point. I’ve stated it as concisely as I can. I hope this becomes the new sound bite that people repeat to their friends, colleagues, and family. Please.&lt;/p&gt;
&lt;h2 id=&quot;only-programmer-tests&quot;&gt;Only Programmer Tests&lt;/h2&gt;
&lt;p&gt;When I talk about the integrated tests scam, I refer to a very specific practice of using integrated tests to “fill the gaps in our unit testing”. Unfortunately, since I usually find myself very deep in this context, &lt;strong&gt;I forget to mention that I’m referring only to programmer tests&lt;/strong&gt; when I write or talk about the scam. This point really, really matters!&lt;/p&gt;
&lt;p&gt;I receive the occasional email—including one today—from people who tell me that they use integrated tests to verify that their features work the way their customers (or stakeholders or product owners…) expect. They are surprised that I would be telling them that they’re doing it wrong. &lt;em&gt;I’m not&lt;/em&gt;. Well… I am and I’m not.&lt;/p&gt;
&lt;p&gt;When I refer to the integrated tests scam, I mean that &lt;strong&gt;we shouldn’t use integrated tests to check the basic correctness of our code&lt;/strong&gt;. I’m talking only about &lt;strong&gt;programmer tests&lt;/strong&gt;: tests designed to give the programmers confidence that their code does what they think they asked it to do. Some people call these “technical-facing tests” or “developer tests” or even “unit tests” (I never use “unit tests”, because that term causes its own confusion, but that’s another article). Whatever you call them, I mean the tests that only the programmers care about that help them feel confident that their code behaves the way they expect. There, I write as few integrated tests as possible.&lt;/p&gt;
&lt;p&gt;When working with &lt;strong&gt;customer tests&lt;/strong&gt;, such as the kind we write as part of BDD or ATDD or STDD or just generally exploring features with customers, I’m not using those tests to check the correctness of the system, nor the health of the design; I’m using those tests to give the customer confidence that the features they’ve asked for are present in the system. I don’t expect design feedback from these tests, so I don’t worry about the integrated tests scam here. If your customer tests run from end to end, I don’t mind; although you should remember that not all customer tests &lt;em&gt;need&lt;/em&gt; to run from end to end. James Shore once told me about “customer unit tests”, which I’ve also used, but that’s another article.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
So, let me clarify again: &lt;strong&gt;the integrated tests scam happens when we use integrated tests for feedback about the basic correctness of our system, and write them in place of microtests that would give us better feedback about our design&lt;/strong&gt;. Don’t do this.
&lt;/p&gt;
&lt;h2 id=&quot;yes-i-need-a-few-integrated-tests&quot;&gt;Yes, I Need A Few Integrated Tests&lt;/h2&gt;
&lt;p&gt;Even with all the foregoing, I still write a small number—very small—of integrated tests. Specifically, I follow the advice &lt;em&gt;don’t mock types you don’t own&lt;/em&gt;—at least most of the time. You’ve seen interfaces that violate the Interface Segregation Principle in the worst possible ways—my canonical example is Java’s &lt;code&gt;ResultSet&lt;/code&gt;—and mocking those interfaces is a sure path towards madness. Even when third-party frameworks and libraries give us interfaces, they are often quite terrible, especially when different methods on the interface duplicate each other’s behavior. (Think of &lt;code&gt;getParameter()&lt;/code&gt; and &lt;code&gt;getParameterMap()&lt;/code&gt; on an HTTP request interface.) When this happens, we face a Morton’s Fork:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Mock all the related methods consistently to avoid contradictions (&lt;code&gt;size()&lt;/code&gt; returns &lt;code&gt;0&lt;/code&gt;, but &lt;code&gt;isEmpty()&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt;), in order to retain the freedom to refactor implementation details, even though that means mocking methods you won’t need.&lt;/li&gt;
&lt;li&gt;Mock only the methods you invoke, leading to brittle tests that fail because you’ve refactored what seems like a completely free implementation detail choice.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some people interpret this as a failing of mock objects. No. I interpret it as a failing of the design. Again—another article. I prefer instead to emphasize the point that I do still write some integrated tests. I do, however, write almost none, and my code tends to flow in the direction of not needing them, and many of the ones I write I end up replacing over time with microtests.&lt;/p&gt;
&lt;aside class=&quot;aside&quot;&gt;
I have a wonderful explanation of this point, but it takes several minutes or hundreds of words, and this article has already grown quite long. I have put it on my backlog to write another article with an example of how I do this. Patience.
&lt;/aside&gt;
&lt;p&gt;I typically don’t mock types that I don’t own. I just integrate with them, write integrated tests, and be done with it. Of course, this creates little Adapters that export third-party behavior as Services to the rest of my system, which I hide behind interfaces that I call a “Patterns of Usage API”. I then mock those interfaces so that the rest of the system neither knows nor cares about the details of integrating with that horrible gelatinous blob. In many cases, &lt;strong&gt;those tests are learning tests for the third-party system&lt;/strong&gt;, rather than tests for “my code”. They become acceptance tests in the classic sense of the term. They become tests for the third-party system, and I run them only when either I need to upgrade or I need to start using some hitherto-unused part of it.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
So yes, I write some integrated tests, but many, many fewer than you, for a specific purpose, and I design in a way to intentionally make them obsolete over time. I write them in a way that avoids the scam. And I certainly don’t use them to check that “the system hangs together”. That way lies the scam.
&lt;/p&gt;
&lt;h2 id=&quot;so-are-we-good&quot;&gt;So… Are We Good?&lt;/h2&gt;
&lt;p&gt;So… I’ve clarified some key differences of understanding regarding the integrated tests scam. Now I can get on with my life, right? Wrong. People will still read the old articles and not the new ones. Other people will perpetuate my mistake from 2009 whether they intend to do it or not. Others still will listen to the sound bites, switch off the brain, and often understand the exact opposite of what I meant. I have made peace with all these things. Even so, I hope that some thoughtful, mindful readers will have more clearly understood the nature of the integrated tests scam, how I use integrated tests effectively, and especially how sorry I am for ever calling them “integration tests” in the first place.&lt;/p&gt;
&lt;p&gt;Not just Canadian sorry. Sorry sorry.&lt;/p&gt;
</description>
        <pubDate>Tue, 08 Dec 2015 08:30:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/clearing-up-the-integrated-tests-scam</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/clearing-up-the-integrated-tests-scam</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Designing the Entry Point</title>
        <description>&lt;p&gt;The entry point. Sometimes it’s &lt;code&gt;main()&lt;/code&gt;. Sometimes it’s an extension point in some complicated framework. Most importantly, it is the border where Their Stuff runs Your Stuff. When I see entry points in other applications, I don’t see a lot of evidence of having thought about the design much. It becomes a kind of junk drawer for code. This happens especially when programmers are working in environments they don’t feel particularly comfortable in. (I don’t know where to put things, so I’ll put them here, since that seems to work.)&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
I use the entry point of an application (or a component, but it’s the same) as the place to wire up my graph of modules (these days, usually objects) and connect my request handlers to the incoming pipeline of requests.
&lt;/p&gt;
&lt;p&gt;That sounds fancy, but in the case of a command-line interface, the incoming pipeline of requests is simply text over standard input, and in the case of a web application, the incoming pipeline of requests is however the framework presents incoming HTTP requests to my code: somewhere between raw requests and nice little bundles of data, neatly structured and sometimes already well-parsed into meaningful data types!&lt;/p&gt;
&lt;p&gt;But really, that’s it. Nothing else happens in the entry point in my designs. I connect my request handlers (often there’s only one, but sometimes many) to the “inbox” of requests, so that I can handle requests. In order to do this, I need to “assemble” my application by connecting all the concrete modules to each other. In object-oriented programming terms, that means instantiating all the services and connecting them together. My entry points do nothing more complicated than that. (That’s plenty complicated as it is.)&lt;/p&gt;
&lt;h2 id=&quot;an-example&quot;&gt;An Example&lt;/h2&gt;
&lt;p&gt;I recently taught the World’s Best Introduction to Test-Driven Development “live and in person”. (I still do that, but my &lt;a href=&quot;//tdd.training&quot;&gt;online training&lt;/a&gt; is a great option for people who don’t want to wait for me to get on a plane and visit them.) Here’s a diagram to show the structure.&lt;/p&gt;
&lt;figure&gt;
&lt;a href=&quot;//images.jbrains.ca/DesigningTheEntryPoint/diagram-1.png&quot;&gt;&lt;img src=&quot;//images.jbrains.ca/DesigningTheEntryPoint/diagram-1-600w.png&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;
The entry point only wires all these objects together, then “presses go” (invokes &lt;code&gt;process()&lt;/code&gt;)
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Once we extract the anonymous implementation of &lt;code&gt;Display&lt;/code&gt; into the production class &lt;code&gt;ConsoleDisplay&lt;/code&gt;, we see that &lt;code&gt;main()&lt;/code&gt; does nothing except wire up the objects and connect &lt;code&gt;Thing&lt;/code&gt; to &lt;code&gt;System.in&lt;/code&gt;. In my opinion, as it should be.&lt;/p&gt;
&lt;p&gt;What’s in &lt;em&gt;your&lt;/em&gt; entry point that probably doesn’t need to be exactly there? Remember: if it’s in the entry point, then you need to run the whole application (and maybe even redeploy it) in order to check it!&lt;/p&gt;
</description>
        <pubDate>Wed, 02 Dec 2015 08:58:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/designing-the-entry-point</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/designing-the-entry-point</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Injecting Dependencies, Partially Applying Functions, and It Really Doesn&apos;t Matter</title>
        <description>&lt;p&gt;You might have noticed &lt;em&gt;dependency injection&lt;/em&gt; gaining popularity in recent years. You might also have noticed some notable figures (I’m thinking of &lt;a href=&quot;https://www.twitter.com/KevlinHenney&quot;&gt;Kevlin Henney&lt;/a&gt;) who &lt;em&gt;appear&lt;/em&gt; to be bad-mouthing dependency injection, when really they are simply taking away what they feel is a veneer of mystery from the term.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; I must say that I appreciate their doing so without pretentious use of the annoying word “demystifying”. (Simply ignore my own “demystifying” article by most certainly not clicking &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;here&lt;/a&gt;. While on a three-hour-long car trip it occurred to me—some would say much too late—that injecting dependencies, particularly through the constructor, acts precisely like partially applying functions. This leads to a couple of potentially useful conclusions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This explains why practising TDD has seemed to be pushing my object-oriented designs in the direction of what appears to be a functional programming design style.&lt;/li&gt;
&lt;li&gt;When test-driving, I see no good reason to rush to label a parameter as a collaborator, so I can defer the decision as long as I want.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, when practising TDD, if I ever have a moment of doubt as to whether a parameter belongs with the object’s constructor or the function/method itself, I stop thinking, put the parameter on the method, and just keep going. No worry, no penalty, no problem.&lt;/p&gt;
&lt;h2 id=&quot;the-tests-dont-care&quot;&gt;The Tests Don’t Care&lt;/h2&gt;
&lt;p&gt;I write &lt;em&gt;microtests&lt;/em&gt;&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, meaning really small tests. I design my microtests to be independent of one another, so that the side-effects of one test don’t affect the results of running another test in the same test run.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; This encourages me to design my production code to make it easy to pass in any useful details (“inject” them), like collaborating services, configuration information, and, of course, request data. Don’t be fooled by my use of &lt;em&gt;request data&lt;/em&gt;: I just mean parameters that vary from request to request, such as the 49 in a call to &lt;code&gt;sqrt(49)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Aha! Since every test lives in its own little world, and sets everything up before running and tears everything down after running, then &lt;em&gt;every parameter in a test is request data&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;A typical application runs for some non-trivial amount of time. Let’s say “days”, just to make it more concrete. While the application is running for days, certain details about the application don’t change much: connections to databases, web services, the file system. These details might change from run to run, but while the application is running, often just as a performance optimization, we don’t change these details. Accordingly, we consider these application-level details quite stable and probably configure them at the very top of our application, just once, and then use those objects in the rest of our system without changing their state. (Worse, we probably scatter these details all over the damn application, &lt;em&gt;putting them directly into code&lt;/em&gt; through hideous anti-patterns like the so-called “Service Locator”.)&lt;/p&gt;
&lt;p&gt;A typical user interacts with our application for some non-trivial amount of time. Let’s say “minutes”, just to make it more concrete. While the user is interacting with our system, certain details about that interaction don’t change much: the user’s authentication credentials, their permissions to perform various actions, their user profile information. Accordingly, we consider these session-level details relatively stable and probably store them in some object attached to the user, changing their state rarely. (Worse, we probably use the session as a dumping-ground for data that we have to pass between ill-designed, overly-interdependent transaction scripts.)&lt;/p&gt;
&lt;p&gt;This leaves the details of each individual micro-interaction that the user has with our application. Each time the user presses a button or selects an item from a list or issues of command from our handy command-line interface. These details change wildly from request to request. Accordingly, we treat them as precious snowflakes, accept them as parameters, put them lovingly on the stack, and then throw them away when we’ve crafted our response and sent it, with care, to the user.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The tests don’t need any of this&lt;/strong&gt;, because each test acts like a separate run of the entire application.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
&lt;span class=&quot;smallcaps&quot;&gt;&lt;strong&gt;Do not, under any circumstances,&lt;/strong&gt;&lt;/span&gt; interpret this to mean that each test runs the entire application from end to end. No. &lt;strong&gt;NO&lt;/strong&gt;. &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;Integrated tests are a scam&lt;/a&gt;, remember?!
&lt;/p&gt;
&lt;p&gt;I mean this: when I write a microtest, which means that it involves &lt;strong&gt;a very small part of the application&lt;/strong&gt;, I can treat each test as a separate run of that part of the application, &lt;strong&gt;and the distinctions between request data, session data, and application data have no value for me at all&lt;/strong&gt;. The “application”, such as it is, runs for such a small amount of time, that these distinctions literally have no meaning &lt;em&gt;in the context of the test&lt;/em&gt;. On the contrary, promoting parameters to the session or application level—which mostly amounts to caching their values—becomes a performance optimization that has value to the application as a whole, but not to the tests. (Moreover, they make the tests harder to understand in most cases.)&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
In fact, when I try to tease apart highly-interdependent legacy code, I spend a lot of energy moving changing details to their “proper” scope. This is why “extract pure functions” works so well: it reduces every detail to a request-scope parameter, then I can use patterns of duplication to figure out how to repackage them more sensibly.
&lt;/p&gt;
&lt;h2 id=&quot;to-a-test-everything-is-request-data&quot;&gt;To A Test, Everything Is Request Data&lt;/h2&gt;
&lt;p&gt;This means that, when we write a test, &lt;em&gt;everything&lt;/em&gt; is request data. &lt;strong&gt;Everything can be a function parameter and the test doesn’t mind&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Great news! This means that, especially when test-driving, we can freely pass every salient detail to the object we’re testing as a method parameter &lt;strong&gt;if that’s convenient&lt;/strong&gt;, then decide later, once the tests pass and we feel all warm and tingly, which parameters to promote to the constructor of some object. Some of those objects have session-oriented lifecycles (like a Shopping Cart or a Locale) and some have application-oriented lifecycles (like an Authentication Service or an Order History).&lt;/p&gt;
&lt;p&gt;But in the tests—oh, boy!—we can just list all the salient details, make them all parameters, invoke the function that interests us, then go on our merry way checking whatever we need to check.&lt;/p&gt;
&lt;h2 id=&quot;so-stop-worrying-and-arguing&quot;&gt;So, Stop Worrying… And Arguing!&lt;/h2&gt;
&lt;p&gt;If you test-drive, then you can literally start by making everything a function parameter to start, then &lt;strong&gt;remove duplication&lt;/strong&gt; and &lt;strong&gt;improve names&lt;/strong&gt; to help identify which parameters you should promote to the constructor. You would end up with a design in which details change at their proper rates. It would totally work. I might even try it.&lt;/p&gt;
&lt;p&gt;Mostly importantly, if you find yourself working with someone who cares deeply about getting this point right, then you can either (1) let the parameter stay on the function until duplication makes it clear that it’s time to promote it to the constructor or (2) let the parameter go to the constructor, secure in the knowledge that it is a purely mechanical refactoring to demote it to the function when it becomes clear that that’s warranted. No arguments. It’ll be fine.&lt;/p&gt;
&lt;h2 id=&quot;uh-partially-applied-functions&quot;&gt;Uh… Partially-Applied Functions?!&lt;/h2&gt;
&lt;p&gt;Oh, yes. And, it so happens, this is exactly what partial application helps with in functional programming languages. We can design functions to take 20 parameters, if we want, but if 18 of them change infrequently (but at the same rate), then we can apply &lt;code&gt;f20&lt;/code&gt; to those 18 parameters, making function &lt;code&gt;f2&lt;/code&gt; that takes only the last two parameters that change most often. I will prefer to invoke &lt;code&gt;f20&lt;/code&gt; in tests for the sake of explicit links between inputs and expected outputs, but I will prefer to invoke &lt;code&gt;f2&lt;/code&gt; in the application for the sake of avoiding duplication, and probably as a performance optimization. (I don’t know: do compilers like the one for Haskell have enough magic to optimize this for me? Probably not, but how cool would that be?!)&lt;/p&gt;
&lt;p&gt;I guess this explains why I’ve had this feeling for several years that practising TDD has nudged my OO designs in the direction of FP-style design. I’ve been partially applying functions, and I even &lt;a href=&quot;https://www.harukizaemon.com/blog/2010/03/01/functional-programming-in-object-oriented-languages/&quot;&gt;knew that I was&lt;/a&gt;—an object is, after all, a cohesive (we hope) collection of partially-applied functions—but I didn’t understand this particular aspect of the significance of those facts until I had a few hours riding in a car for it to occur to me.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;“Demystifying the Dependency Inversion Principle”&lt;/a&gt;. A few ways to explain this critical-but-often-misunderstood design principle.&lt;/p&gt;
&lt;p&gt;Simon Harris, &lt;a href=&quot;https://www.harukizaemon.com/blog/2010/03/01/functional-programming-in-object-oriented-languages/&quot;&gt;“Functional programming in object oriented languages”&lt;/a&gt;. A wonderful answer to the question “How does design change between OO and FP styles?”&lt;/p&gt;
&lt;p&gt;Ingmar van Dijk, &lt;a href=&quot;https://www.industriallogic.com/blog/history-microtests/&quot;&gt;“The History of Microtests”&lt;/a&gt;. A retrospective on the origins of the term &lt;em&gt;microtests&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Kent Beck, &lt;a href=&quot;https://link.jbrains.ca/172z2KZ&quot;&gt;&lt;em&gt;Test Driven Development: By Example&lt;/em&gt;&lt;/a&gt;. This remains the classic text on the topic, complete with examples of the tiny steps that help me keep the cost of mistakes low.&lt;/p&gt;
&lt;p&gt;Chris Oldwood, &lt;a href=&quot;https://chrisoldwood.blogspot.co.uk/2014/04/terminology-overdose.html&quot;&gt;“Terminology Overdose”&lt;/a&gt;. Don’t let a new term get in the way of understanding an old idea.&lt;/p&gt;
&lt;p&gt;Kris Jenkins, &lt;a href=&quot;https://blog.jenkster.com/2015/12/what-is-functional-programming.html&quot;&gt;“What Is Functional Programming?”&lt;/a&gt;. Another article that argues both sides of implicit dependencies, describing functional programming as designing side effects with care. (I’d call this “programming”, myself.)&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I consider it categorically unfair to interpret what Kevlin writes or &lt;a href=&quot;https://chrisoldwood.blogspot.co.uk/2014/04/terminology-overdose.html&quot;&gt;Chris Oldwood&lt;/a&gt; writes as “bad-mouthing” the &lt;em&gt;concept&lt;/em&gt; of dependency injection, but unfortunately, a careless reading of their work might suggest that in the mind of the careless reader. They mostly object to coining a new term for an old idea, with which I agree. Even so, &lt;em&gt;dependency injection&lt;/em&gt; remains known as a term of art, so I just want to roll with it.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I learned the term from &lt;a href=&quot;https://www.twitter.com/GeePawHill&quot;&gt;Michael Hill&lt;/a&gt;, who uses it in part to avoid the whole “what is a unit?” navel-gazing exhibition.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I learned this principle from &lt;a href=&quot;https://www.twitter.com/KentBeck&quot;&gt;Kent Beck&lt;/a&gt;’s “daily bug reports” story, which I think I first read in one of the early &lt;a href=&quot;https://link.jbrains.ca/UNqq44&quot;&gt;XP&lt;/a&gt; &lt;a href=&quot;https://link.jbrains.ca/10Ys86c&quot;&gt;books&lt;/a&gt;.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Fri, 13 Nov 2015 03:30:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/injecting-dependencies</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/injecting-dependencies</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>How To Recover From the Integrated Tests Scam</title>
        <description>&lt;p&gt;A Twitter follower asked me how to recover from feeling overwhelmed by too many integrated tests, calling it “a common struggle of mine”.&lt;/p&gt;
&lt;p&gt;If you haven’t seen &lt;a href=&quot;https://vimeo.com/80533536&quot;&gt;this video (64 minutes)&lt;/a&gt;, then you might not quite know what I mean by “integrated tests”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If a test passes or fails based on the behavior of many “interesting” bits of behavior, then I call it an &lt;em&gt;integrated&lt;/em&gt; test. (Not an &lt;em&gt;integration&lt;/em&gt; test—those check the integration between layers of a system.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Integrated tests tend to be big, because they run multiple layers of the system together. They tend to cause trouble because either they check too many things and confuse the programmer or they check only one thing and waste a lot of time doing it. I prefer, instead, to write as many isolated or microtests as possible, which run one thing and check that one thing and that’s that.&lt;/p&gt;
&lt;p&gt;Nevertheless, most groups that practise TDD seriously eventually fall into the integrated tests scam to some degree.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/HowToRecoverFromTheIntegratedTestsScam/image-1.jpg&quot; /&gt;
&lt;figcaption&gt;
The integrated tests scam
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When it happens for long enough, more of the system becomes tightly interdependent, it becomes harder to test anything (whether with &lt;em&gt;integrated tests&lt;/em&gt; or with &lt;em&gt;microtests&lt;/em&gt;), and then they’re stuck in the mud: can’t dig out, can’t move forward.&lt;/p&gt;
&lt;p&gt;Well… not &lt;em&gt;can’t&lt;/em&gt;. It does, however, seem daunting. Even if you know that you ought to start teasing things apart, it goes slowly. You feel pain. Little victories seem like very hard work and significant progress seems impossible. This leads to the feeling of being overwhelmed.&lt;/p&gt;
&lt;h2 id=&quot;the-best-time-to-start&quot;&gt;The Best Time To Start…&lt;/h2&gt;
&lt;p&gt;The old joke advice goes like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The best time to start was five years ago. The next-best time to start is now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a consultant, I often have to give this kind of “dissatisfying but true” advice. To deal with legacy code and crawl out of the integrated tests scam, you just have to start. You have to start trying to add tests, trying to tease code slowly apart, trying to improve the design just a little every day. Eventually, these improvements compound and, months from now, over a weekend, suddenly the improvements mean something. Then you gain confidence. Then you feel better. Then you celebrate.&lt;/p&gt;
&lt;h2 id=&quot;where-do-i-start&quot;&gt;Where Do I Start?&lt;/h2&gt;
&lt;p&gt;One of the most common questions people ask me about refactoring, is &lt;em&gt;Where do I start?&lt;/em&gt; I even turned this question into a popular conference talk about a decade ago. The bad news with this situation is that there’s no good place to start. The good news is that there’s no bad place to start, either. Just start. Anywhere. Really.&lt;/p&gt;
&lt;p&gt;I intend this advice to feel liberating, but most people find it disheartening. &lt;em&gt;Great! It doesn’t matter where we start! It’s hopeless!&lt;/em&gt; No. I offer you this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Great! It doesn’t matter where we start! We can start wherever we want!!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, you can. Even if there is an optimal place to start rescuing your design, nobody can see it right now. It lies buried under the rubble of a thousand compromises. Even the greatest tools will only help you a little. Picking a place to start by random chance will give you a roughly equally good chance of a reasonable return on your investment.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/HowToRecoverFromTheIntegratedTestsScam/image-2.jpg&quot; /&gt;
&lt;figcaption&gt;
Good news, everyone!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;No matter where you start adding tests or teasing apart code, it’ll feel slow, annoying, and painful. It’ll make you laugh, cry, throw things against the wall. It’ll make you sweat. It’ll take months, even years, to get better.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So get started.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;while-i-have-you&quot;&gt;While I Have You…&lt;/h2&gt;
&lt;p&gt;You probably already know about my online training school at &lt;a href=&quot;https://online-training.jbrains.ca&quot;&gt;online-training.jbrains.ca&lt;/a&gt;. I’m planning the next course, and I’d like your help. It’ll take 30 seconds, depending on the speed of your internet connection. It’s a one-question survey. Please answer it by &lt;a href=&quot;https://jbrains.typeform.com/to/GCSL41&quot;&gt;clicking here&lt;/a&gt;. Thanks.&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Nov 2015 17:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-to-recover-from-the-integrated-tests-scam</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-to-recover-from-the-integrated-tests-scam</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Null: Design Tool</title>
        <description>&lt;p&gt;This article describes an evolutionary design microtechnique. Specifically, it describes a &lt;em&gt;weak signal&lt;/em&gt; that I use to guide myself towards more modular designs. I find it both simple and surprising: simple because it involves using a single value, but surprising because it involves a value that programmers largely recommend &lt;em&gt;against&lt;/em&gt; using. I refer to the humble &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Yes: I have found a way to use &lt;code&gt;null&lt;/code&gt; that doesn’t lead to heartache.&lt;/p&gt;
&lt;aside class=&quot;aside&quot;&gt;
Even if you don’t program with objects, you’ll probably find this useful. Keep reading.
&lt;/aside&gt;
&lt;p&gt;I start with injecting collaborators through the constructor. (I won’t justify this technique in this article. I’ve done that elsewhere for over a decade.) For example, when using the Web flavor of the MVC pattern—admittedly the weaker flavor of MVC, but not my immediate concern here—I typically inject the Model and View into the Controller.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class SellOneItemController:
  # catalog and display are protocols
  # or interfaces
  # or abstract type descriptors
  constructor(catalog, display):
    self.catalog = catalog
    self.display = display&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apparently we have a point of sale terminal and a controller responsible for selling a single Item to a Shopper. (I’ll capitalize the domain concepts so that they stand out a little.) Selling an Item involves scanning a barcode, then seeing its price on the display that typically faces the Shopper (as opposed to the one that the Cashier can see, which might have more details). Of course, we can only see the price if our Catalog contains a listing for the scanned barcode. If the Catalog doesn’t recognize the barcode, then the controller asks the display to display a message that both the Cashier and the Shopper can understand. You can probably picture the resulting code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class SellOneItemController:
  on_barcode(barcode):
    price = catalog.find_price(barcode)
    if price:
      display.display_price(price)
    else:
      display.display_product_not_found_message(barcode)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More importantly, you can probably picture the corresponding tests. I stub the query and expect the action, following the sensible maxim “Stub Queries; Expect Actions”.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SellOneItemControllerTests:
  # .cents() builds a Price value
  product_found:
    # a totally made-up test double API
    catalog, display = double(&amp;quot;a Catalog&amp;quot;), double(&amp;quot;a Display&amp;quot;)

    stub(catalog).find_price(&amp;quot;12345&amp;quot;).and_return(795.cents)
    expect(display).display_price(795.cents)

    SellOneItemController(catalog, display).on_barcode(&amp;quot;12345&amp;quot;)

  product_not_found:
    catalog, display = double(&amp;quot;a Catalog&amp;quot;), double(&amp;quot;a Display&amp;quot;)

    stub(catalog).find_price(&amp;quot;12345&amp;quot;).and_return(null)
    expect(display).display_product_not_found_message(&amp;quot;12345&amp;quot;)

    SellOneItemController(catalog, display).on_barcode(&amp;quot;12345&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To read these tests in English:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pretend that the Catalog has barcode “12345” with price $7.95 (or 7.95€, if you prefer). In that case, when the controller receives barcode “12345”, something must display the price $7.95 (7.95€).&lt;/li&gt;
&lt;li&gt;Pretend that the Catalog doesn’t have a price for barcode “12345”. In that case, when the controller receives barcode “12345”, something must display a message that somehow conveys “product not found” for the barcode “12345”.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So far, so good. As a programmer with &lt;em&gt;some&lt;/em&gt; testing skill, I imagine some special &lt;em&gt;boundary&lt;/em&gt; values for &lt;code&gt;barcode&lt;/code&gt; that might cause trouble, such as our friend the empty string (&lt;code&gt;&quot;&quot;&lt;/code&gt;). Sure enough, I can imagine that a text-based display might create problems for the Shopper and the Cashier if we happen to scan an empty barcode. We might see a message like this:&lt;/p&gt;
&lt;p class=&quot;user-displayed-message&quot;&gt;
Product not found for
&lt;/p&gt;
&lt;p&gt;We programmers can see the empty string at the end of that message, but a Shopper or Cashier might think that something is broken, and rightly so. I’d prefer to do something less likely to create problems. Of course, I start with a test.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SellOneItemControllerTests:
  # blah blah blah...
  empty_barcode:
    catalog, display = double(&amp;quot;a Catalog&amp;quot;), double(&amp;quot;a Display&amp;quot;)

    expect(display).display_scanned_empty_barcode_message()

    SellOneItemController(catalog, display).on_barcode(&amp;quot;&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wait a moment… what about stubbing the Catalog? &lt;strong&gt;We don’t need to.&lt;/strong&gt; Therein lies a clue.&lt;/p&gt;
&lt;h2 id=&quot;choices&quot;&gt;Choices…&lt;/h2&gt;
&lt;p&gt;If we leave things as they are, then what happens next depends on the test double library I use. If I use JMock, then my production code &lt;em&gt;may not&lt;/em&gt; invoke anything on the &lt;code&gt;catalog&lt;/code&gt; on pain of making the test fail. If I use Mockito, then my production code &lt;em&gt;may&lt;/em&gt; send messages to the &lt;code&gt;catalog&lt;/code&gt;, and nobody will care. Some libraries refer to these as “strict” and “lenient” modes, respectively. For this test, either behavior will do, because I don’t intend to use the &lt;code&gt;catalog&lt;/code&gt; in this branch of the production code; instead, I’ll end up with something like what follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class SellOneItemController:
  on_barcode(barcode):
    if barcode.empty?:
      display.display_scanned_empty_barcode_message()
      return

    price = catalog.find_price(barcode)
    if price:
      display.display_price(price)
    else:
      display.display_product_not_found_message(barcode)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t intend to discuss the Guard Clause here, beyond saying that I prefer it to the alternatives that I know about. If you want to suggest something better, then &lt;a href=&quot;https://tell.jbrains.ca/&quot;&gt;click here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-key-observation&quot;&gt;The Key Observation&lt;/h2&gt;
&lt;p&gt;I notice two things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;&lt;code&gt;on_barcode()&lt;/code&gt; has a code path that doesn’t invoke the &lt;code&gt;catalog&lt;/code&gt; at all.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SellOneItemControllerTests.empty_barcode&lt;/code&gt; doesn’t need to stub any behavior on the &lt;code&gt;catalog&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Of course, these two things relate to each other, both signaling the same underlying risk: we have a code path inside &lt;code&gt;SellOneItemController&lt;/code&gt; that ignores one of its collaborators. I call this a &lt;em&gt;risk&lt;/em&gt;, because it doesn’t necessarily signal a &lt;em&gt;problem&lt;/em&gt;, but rather a potential problem in the future. Moreover, I can make this risk even more explicit with my simple trick.&lt;/p&gt;
&lt;h2 id=&quot;the-trick&quot;&gt;The Trick!&lt;/h2&gt;
&lt;p&gt;If we don’t need a collaborator, then let’s really say so.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SellOneItemControllerTests:
  # blah blah blah...
  empty_barcode:
    display = double(&amp;quot;a Display&amp;quot;)

    expect(display).display_scanned_empty_barcode_message()

    # The Trick! I don&amp;#39;t need a catalog at all.
    SellOneItemController(null, display).on_barcode(&amp;quot;&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I can pass &lt;code&gt;null&lt;/code&gt; as the value for a collaborator, then I do. This signals something potentially interesting to me: a code path through the &lt;em&gt;subject under test&lt;/em&gt; ignores that collaborator. On its own, a single path like this matters not at all. A few paths like this, however, signal that &lt;strong&gt;perhaps the subject under test has too many responsibilities&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You might think that I’ve gone mad. You might think that I’ve started over-engineering by suggesting that &lt;code&gt;on_barcode()&lt;/code&gt; has too many responsibilities. Look at how small it is! For that reason, I called this a &lt;em&gt;weak signal&lt;/em&gt; pointing to a &lt;em&gt;risk&lt;/em&gt;. I can’t say that this causes a problem just yet, but I prefer to think about these issues earlier, when addressing the problem generally costs less.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
When a kitten scratches you, it hurts. When a lion scratches you, you die. I like to consider design problems as kittens, rather than waiting until they become lions. Or spirit-crushing legacy code.
&lt;/p&gt;
&lt;h2 id=&quot;the-evidence&quot;&gt;The Evidence (?)&lt;/h2&gt;
&lt;p&gt;Once again, when I have only one code path that ignores a collaborator, then I can’t justify concluding definitively that I should split the module (or class) into pieces just yet; however, I can absolutely justify taking a few moments to consider it. More importantly, I can justify wondering what test (or feature) I’d have to write to force myself to confront the issue more seriously—how might I gather evidence that I should split this behavior from the rest of the module (or class)? If I can think of this in a few seconds, and if that behavior is on the immediate list to implement, then I favor choosing that test sooner; and if not, then I don’t.&lt;/p&gt;
&lt;p&gt;In this case, I don’t encounter this issue again until I implement more of the system: notably when I connect the hardware. If you want the details, then you’ll have to sign up for my online TDD training, but I can give you a preview here.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Why does &lt;code&gt;on_barcode()&lt;/code&gt; need to even worry about the empty string? Because the language doesn’t easily let us declare the &lt;code&gt;barcode&lt;/code&gt; parameter in a way that rejects the empty string.&lt;/li&gt;
&lt;li&gt;How do we even get an empty string at all? It depends on how we implement the UI. With some barcode scanner hardware, it can’t happen, but with a computer keyboard, I could just hit ENTER without entering a barcode.&lt;/li&gt;
&lt;li&gt;Who bears responsibility for rejecting the empty string as a barcode? Ideally, only one part of the code base. It really depends on the consequences of processing an empty string, and that becomes an accident of implementation. In our case, so far, the controller simply wouldn’t find a price for the barcode, and would display a confusing message to the Shopper and Cashier. Tolerating that or not becomes a business decision.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When we connect the hardware, we eventually build the thing—you know, the &lt;em&gt;thing&lt;/em&gt;—that listens to &lt;code&gt;stdin&lt;/code&gt; and hands lines of text over to something that interprets them as barcodes or other kinds of commands. This thing—call it a Text Command Consumer—also has to decide how to process empty commands. It can blithely ask the interpreter to interpret them, or it can helpfully (?) reject them as uninterpretable. This becomes a design decision. What we do here determines what we do in &lt;code&gt;SellOneItemController&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the one hand, we could tell the controller not to worry: we could make its clients filter empty barcodes out. We could also tell the controller that it has to defend itself against an attack that it should blame on the programming language in question. (In another language, we could define a data type that excludes the empty string. In Java, we could make &lt;code&gt;on_barcode()&lt;/code&gt; take a &lt;code&gt;Barcode&lt;/code&gt; that can’t be empty. We have ways.)&lt;/p&gt;
&lt;p&gt;I find it comforting to know that, by passing &lt;code&gt;null&lt;/code&gt; as the &lt;code&gt;catalog&lt;/code&gt; collaborator, I had to consider all this; otherwise, this detail could go unconsidered, leading to a classic “You were supposed to handle that!” problem weeks or months from now.&lt;/p&gt;
&lt;p&gt;So there you have it: &lt;code&gt;null&lt;/code&gt; doesn’t always have to suck. Enjoy.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
You can find more of this as part of my online training course, &lt;a href=&quot;https://wbitdd.jbrains.ca&quot;&gt;&lt;em&gt;The World’s Best Intro to TDD&lt;/em&gt;&lt;/a&gt;.
&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Tony Hoare, &lt;a href=&quot;https://link.jbrains.ca/billion-dollar-mistake&quot;&gt;“Null References: The Billion-Dollar Mistake”&lt;/a&gt;. If you made a mistake that cost an entire industry billions of dollars over the length of your career, would you have the courage to admit it publicly?&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/injecting-dependencies-doesnt-have-to-hurt&quot;&gt;“Injecting Your Dependencies Doesn’t Have to Hurt”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/vN1IiF&quot;&gt;“Injecting Testability Into Your Design”&lt;/a&gt;. (&lt;em&gt;Originally published in Better Software, April 2005.&lt;/em&gt;) In this article I describe how and why, including walking the reader through an example.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/1ymPozy&quot;&gt;“An answer to, ‘What are the advantages and disadvantages when we are implementing the dependency injection?’”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Steve Freeman and Nat Pryce, &lt;a href=&quot;https://link.jbrains.ca/10nrSjg&quot;&gt;&lt;em&gt;Growing Object-Oriented Software, Guided by Tests&lt;/em&gt;&lt;/a&gt;. This fantastic book includes such gems as “Stub Queries; Expect Actions”. Run, don’t walk, to your local large multinational conglomerate and buy a copy today!&lt;/p&gt;
&lt;p&gt;Tom DeMarco and Tim Lister, &lt;a href=&quot;https://link.jbrains.ca/S2jyPY&quot;&gt;&lt;em&gt;Waltzing with Bears&lt;/em&gt;&lt;/a&gt;. My favorite manual for managing risk on software projects. It includes the definitions of &lt;em&gt;risk&lt;/em&gt; as a potential problem and &lt;em&gt;problem&lt;/em&gt; as a realized risk.&lt;/p&gt;
</description>
        <pubDate>Fri, 29 May 2015 07:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/null-design-tool</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/null-design-tool</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>What Good is Subclass to Test, Anyway?</title>
        <description>&lt;blockquote&gt;
&lt;p&gt;We recently ran a legacy code retreat based on your format. People were questioning the value of subclass-to-test in a real world scenario. The best reason I could come up with for myself was that it’s a smaller step to separating out responsibilities from a class.&lt;/p&gt;
&lt;p&gt;How would you frame the value of subclass-to-test, and in which contexts would you use it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I view Subclass to Test as an intermediate step towards other refactorings like Replace Inheritance with Delegation, Introduce Named Constructors, and especially Separate Lifecycle Management from Lifecycle Behavior. I see Subclass to Test has a highly mechanical way to start identifying how to split things apart. (I just follow the steps and don’t have to know where the design is going yet.) It’s easy to say “we need to split things apart”, but Subclass to Test helps me see specific patterns, for example, in the difference between setting up state and doing something interesting. Referring to the &lt;a href=&quot;https://www.github.com/jbrains/trivia&quot;&gt;Legacy Code Retreat code&lt;/a&gt;, does your test check addPlayer() or roll()? Do you only call addPlayer() so that you have players who can roll()? What if you could call roll() on an object with the necessary players without worrying about how to make that happen? What if you could call roll() on an object that doesn’t care about players?! If we separated the Board from the Rules from the Players, then it would be easier to add things like save/restart, which would make playing the game online more robust…. By only committing up front to Subclass to Test, I remain open to options without over-committing to one, specific, narrow refactoring.&lt;/p&gt;
&lt;p&gt;So I see two main benefits to Subclass to Test:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I don’t know where the design needs to go, so I can start with Subclass to Test, look for patterns in the subclasses, then decide later.&lt;/li&gt;
&lt;li&gt;I think I know where the design needs to go, but I don’t feel comfortable going there safely in one big step, so I can start with Subclass to Test, do those steps safely and correctly, then continue with the design improvements that I had in mind. (Sometimes here I realize that I was wrong, and I have a chance to change direction without undoing all my good work.)&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 07 Apr 2015 03:30:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/what-good-is-subclass-to-test</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/what-good-is-subclass-to-test</guid>
        
        
      </item>
    
      <item>
        <title>Your Tests Are Dragging You Down</title>
        <description>&lt;p&gt;I’ve written in the past that &lt;a href=&quot;https://bit.ly/QWK7do&quot;&gt;integrated tests are a scam&lt;/a&gt;, but that’s not what I mean here.&lt;/p&gt;
&lt;aside&gt;
Even if you’re not a programmer, read on. There’s something in this for you, too, and you’ll probably want to share it with the programmers around you. I promise.
&lt;/aside&gt;
&lt;p&gt;Dear programmers, your tests are probably dragging you down. Here we have another delightful irony of agile software development, this time related to test-driven development. I give you The Fundamental Irony of Test-Driven Development.&lt;/p&gt;
&lt;figure&gt;
&lt;p class=&quot;highlight&quot;&gt;
If you practise test-driven development, then depending on how you manage your short-term tasks, you run the risk of &lt;em&gt;increasing&lt;/em&gt; your stress levels compared to not doing test-driven development at all.
&lt;/p&gt;
&lt;figcaption&gt;
The Fundamental Irony of Test-Driven Development
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Strange, isn’t it? Here’s how it works:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Practising TDD encourages you to break your work down into microtasks: in many cases, individual tests. This clarifies what you intend to do, by breaking it down into more, small tasks.&lt;/li&gt;
&lt;li&gt;You’re used to keeping the salient details of your current work in your mind’s short-term memory, even when you work for a few hours at a time.&lt;/li&gt;
&lt;li&gt;Now, you have even more details to try to keep in your head while you work. Congratulations!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It reminds me of some companies who adopt Scrum, switch from weekly status meetings to monthly sprint reviews, and the flow of information about the progress of the project actually goes &lt;em&gt;down&lt;/em&gt;. Great, no?&lt;/p&gt;
&lt;p&gt;This bears repeating.&lt;/p&gt;
&lt;div class=&quot;highlight space-above-paragraph&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;Practising TDD while keeping everything in your head:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;decreases&lt;/strong&gt; focus&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hurts&lt;/strong&gt; productivity&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;wastes&lt;/strong&gt; precious energy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;increases&lt;/strong&gt; stress&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;You didn’t see that coming, did you? Maybe you did.&lt;/p&gt;
&lt;p&gt;It doesn’t happen right away, mind you. You probably found TDD a relief when you first started practising it. The constant sense of completion. The continuous positive feedback. The orderly progress towards working, solid code. It feels fantastic… but maybe you’ve noticed a few unexpected side effects.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tasks drag on: often when you think you’re done you notice one more test that you’d forgot to write.&lt;/li&gt;
&lt;li&gt;Thinking about all those error cases and side effects up front makes every feature feel like &lt;em&gt;so much work&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;In the planning meeting it seems like you need half a day, but once you get going it feels like it’s never going to end.&lt;/li&gt;
&lt;li&gt;When you get near the end of a task, you can’t shake this feeling that you’ve forgot something important.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In your weakest moments, it might encourage you to long for the days when you didn’t think about your work quite so systematically and carefully. It’s like writing your second book: once you see how much work it takes to write one, many authors can’t stomach going through it again.&lt;/p&gt;
&lt;h2 id=&quot;kent-beck-to-the-rescue&quot;&gt;Kent Beck To the Rescue!&lt;/h2&gt;
&lt;p&gt;Naturally, Kent Beck had good advice for us way back in his seminal book &lt;a href=&quot;https://link.jbrains.ca/172z2KZ&quot;&gt;&lt;em&gt;Test-Driven Development: By Example&lt;/em&gt;&lt;/a&gt;. He encouraged us to start a programming session by writing a &lt;em&gt;test list&lt;/em&gt;: literally a list of the tests that we think we’ll need to write. As we make tests pass, we cross them off the list; as we think of more tests to write, we add them to the list. When we’ve crossed the last item off the list, we’re done! Simple.&lt;/p&gt;
&lt;p&gt;As you might expect, this advice can help anyone, and not just programmers. It just so happened that Kent aimed the advice at programmers writing tests. The more generic version of this advice can help everyone:&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
When you sit down to work, start by getting things out of your head!
&lt;/p&gt;
&lt;h2 id=&quot;a-few-basic-rules&quot;&gt;A Few Basic Rules&lt;/h2&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;Your enthusiasm will drag you down if you don’t do something about all those ideas buzzing around inside your mind.&quot;&gt;&lt;/span&gt; If you’re a programmer, then the moment you hear about a programming problem, you probably start solving it in your head. Your enthusiasm will drag you down if you don’t do something about all those ideas buzzing around inside your mind. Thinking in terms of tests helps organize your thoughts, but if you keep them all inside, they’ll crush you. Try this the next time you sit down to program:
&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Get yourself something to write with and something to write on.&lt;/li&gt;
&lt;li&gt;Sit comfortably. (So many people overlook this one.)&lt;/li&gt;
&lt;li&gt;Take all the ideas buzzing around your mind and &lt;em&gt;write them down&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Draw some high-level design diagrams&lt;/li&gt;
&lt;li&gt;List the tests that have leapt to mind&lt;/li&gt;
&lt;li&gt;List any refactorings that you already know you might need to do&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Once your mind feels quiet, pick a test and start test-driving.&lt;/li&gt;
&lt;li&gt;As ideas pop into your head, quickly write them down.
&lt;ul&gt;
&lt;li&gt;Add some tests or refactorings to your list.&lt;/li&gt;
&lt;li&gt;If unrelated work pops in your head (“I need to prepare for that damn meeting tomorrow morning…”), write that anywhere else: on another page, in a notebook, wherever.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;As you make tests pass, cross them off the list.&lt;/li&gt;
&lt;li&gt;As you perform the refactorings you had in mind, cross them off the list.&lt;/li&gt;
&lt;li&gt;Repeat until you can’t think of anything more to do to complete your task.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;OK: more than a few rules, but only because I want to leave less room for differences of understanding or interpretation.&lt;/p&gt;
&lt;p&gt;A few things to keep in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just because you write the test or refactoring on your list, that doesn’t mean that you have to do it. If you don’t need it, then &lt;em&gt;don’t do it&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;When first getting things out of your head, don’t try to list &lt;em&gt;all&lt;/em&gt; the tests that you &lt;em&gt;might&lt;/em&gt; need. Focus on listing all the tests that immediately come to mind. First, &lt;strong&gt;unburden yourself&lt;/strong&gt;, then you’ll find it easier to notice that you’ve missed something.&lt;/li&gt;
&lt;li&gt;I write tests from the top of the card or page and refactorings from the bottom. I guess that’s just personal style.&lt;/li&gt;
&lt;li&gt;When you finish your programming task, if you have other work left over, then put it wherever it needs to go in order for you to follow up: email, calendar, to do list, whatever system you use.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;even-simpler&quot;&gt;Even Simpler…&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.imdb.com/title/tt0086879/?ref_=fn_al_tt_1&quot;&gt;It’s no good to anyone in your head, Mozart. Write it down.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Not only that, but I like the satisfaction of crossing things off and ripping up cards when I’m done with them. What can I say? Little things like that amuse me. Whatever works.&lt;/p&gt;
&lt;p&gt;So don’t let your tests drag you down. Lighten the load by getting them out of your head. Try it now! I’ll wait.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Kent Beck, &lt;a href=&quot;https://link.jbrains.ca/172z2KZ&quot;&gt;&lt;em&gt;Test-Driven Development: By Example&lt;/em&gt;&lt;/a&gt;. When you reach a certain point in studying a field, you long you read the classics. If you’ve reached that point, then read this classic.&lt;/p&gt;
&lt;p&gt;David Allen, &lt;a href=&quot;https://link.jbrains.ca/WOXFIr&quot;&gt;&lt;em&gt;Getting Things Done&lt;/em&gt;&lt;/a&gt;. When I first read &lt;em&gt;Getting Things Done&lt;/em&gt;, with its emphasis on getting things out of your head, I immediately recalled Kent’s “Test List” trick. As much as Test Lists helped me with programming tasks, getting everything out of my head has helped with the rest of my work. You can’t imagine the difference until you try it. David’s trademark: &lt;em&gt;Your mind is for having ideas, not holding them.&lt;/em&gt; Kinda cultish, but true.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/getting-started-with-gtd&quot;&gt;“Getting Started with Getting Things Done”&lt;/a&gt;. If you’re not eager to read 200 pages of productivity advice, then start with a handful. I give you enough detail to try the basics of the system for a few days and decide whether you want to learn more. How agile of me!&lt;/p&gt;
&lt;h2 id=&quot;reactions&quot;&gt;Reactions&lt;/h2&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
Been working like this for more than a year, probably influenced by &lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;&lt;/a&gt; workshop &lt;a href=&quot;https://t.co/xOuN1I75kY&quot;&gt;https://t.co/xOuN1I75kY&lt;/a&gt;
&lt;/p&gt;
— Giorgio Sironi (&lt;span class=&quot;citation&quot; data-cites=&quot;giorgiosironi&quot;&gt;@giorgiosironi&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/giorgiosironi/status/588579169178488833&quot;&gt;April 16, 2015&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;If you don’t have a system, then you’ll need one, but let’s solve one problem at a time.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sat, 28 Mar 2015 03:30:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/your-tests-are-dragging-you-down</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/your-tests-are-dragging-you-down</guid>
        
        
      </item>
    
      <item>
        <title>Your Constructors are Completely Irrational</title>
        <description>&lt;p&gt;When clients ask me to &lt;a href=&quot;https://link.jbrains.ca/1tC0bDa&quot;&gt;help them with legacy code&lt;/a&gt; it generally takes less than 30 minutes for me to run into a &lt;em&gt;debilitating constructor&lt;/em&gt;—a term I use to describe a constructor that does too much. You might think me melodramatic for calling it “debilitating”, but these constructors not only slow us down when we try to understand the code, but block our every effort to improve it. These constructors often hardwire a dependency either to some horrifying external resource (a database or a web service end point) or into a framework (even something as “simple” as threads or a lifecycle manager). These constructors also often grow to dozens, and in some extreme cases hundreds, of lines. These constructors kill code bases and, by extension, suck the life out of programmers.&lt;/p&gt;
&lt;p&gt;Do not underestimate the power of the debilitating constructor. If you need convincing, then &lt;a href=&quot;https://link.jbrains.ca/1tC0DRV&quot;&gt;take ten minutes now and click here&lt;/a&gt; to read a more in-depth description of the damage these constructors do.&lt;/p&gt;
&lt;h2 id=&quot;let-me-tell-you-what-im-looking-for-in-a-fucking-constructor&quot;&gt;Let Me Tell You What I’m Looking For in a Fucking Constructor…&lt;/h2&gt;
&lt;aside&gt;
If you don’t recognize this reference, then you don’t know the comedy of Ron White, then shame on you. Go find some now and listen to it. I’ll wait.
&lt;/aside&gt;
&lt;p&gt;A constructor has one job: build objects. You can see that right in the name. I want constructors to build objects.&lt;/p&gt;
&lt;h3 id=&quot;an-anti-pattern-while-im-in-the-neighborhood&quot;&gt;An Anti-Pattern, While I’m In the Neighborhood&lt;/h3&gt;
&lt;p&gt;Every so often I stumble across a test that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;assertNotNull(new EnterpriseCodeBaseSingletonProxyFactory(parameter, parameter, ...));&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I see this, I have the typical alpha programmer impulse to belittle the programmer who wrote this test. I take a few deep breaths to let that feeling pass. True, in Java, the language specification guarantees that every constructor either return a non-null reference or throw an exception; however, in languages that let you do whatever you want with &lt;code&gt;new&lt;/code&gt; (like C++), you can’t make that assumption. Moreover, &lt;strong&gt;after you’ve seen enough debilitating constructors, you assume that every constructor you touch wants to kill you&lt;/strong&gt;. Rightly so. This makes &lt;code&gt;assertNotNull(new X())&lt;/code&gt; almost look reasonable. (It still isn’t reasonable in Java, so please just stop doing this in Java. You have bigger problems.)&lt;/p&gt;
&lt;h2 id=&quot;constructors-cant-reveal-intent&quot;&gt;Constructors Can’t Reveal Intent&lt;/h2&gt;
&lt;p&gt;I limit constructors to building objects (as opposed to connecting to databases) in part because constructors in many languages can’t reveal intent. In Java, C#, C++ and its cousins, you must name the constructor after the class to which it belongs. You may not change the name. Those languages expressly forbid constructors from expressing their intent to do anything more complicated. &lt;strong&gt;As a defence mechanism, I limit constructors to very specific behavior, so that I never have to guess what a constructor will do.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-should-constructors-do-then&quot;&gt;What Should Constructors Do, Then?&lt;/h2&gt;
&lt;p class=&quot;highlight&quot;&gt;
I expect constructors to initialize new instances to a “rational” state.
&lt;/p&gt;
&lt;p&gt;When I encounter a constructor that doesn’t do this, I end up having to grope around in the dark looking for the magic sequence of method invocations that allows me to put the object in a suitable state so that I have even a modicum of confidence that I can safely invoke the method that I really need to invoke. Taking a cue from the Pragmatic Programmers, I too call this &lt;a href=&quot;#programming-by-coincidence&quot;&gt;&lt;em&gt;programming by coincidence&lt;/em&gt;&lt;/a&gt;—although sometimes I call it programming by accident.&lt;/p&gt;
&lt;p&gt;Programmers routinely and drastically underestimate the time, effort, and energy wasted by dealing with constructors that leave new instances in some half-initialized, irrational state.&lt;/p&gt;
&lt;p&gt;Initializing instances to a rational state means assigning values to enough fields to avoid spurious runtime errors like null pointers/references or illegal/unexpected states. If you’ve initialized an instance to a rational state, then I feel confident that I can invoke any method on the object without fear of it belching red smoke in my face. I find this expectation entirely reasonable, don’t you?&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
I also expect constructors to &lt;strong&gt;only&lt;/strong&gt; initialize new instances to a rational state.
&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;So don’t make design decisions that force you to change code that you’re afraid to change. Really.&quot;&gt;&lt;/span&gt; Erik Dietrich covered this case particularly well in his article, so I won’t repeat all that detail here. We can agree that a constructor &lt;em&gt;always needs&lt;/em&gt; to initialize new instances, and we might even agree by now that a constructor &lt;em&gt;always needs&lt;/em&gt; to initialize instances &lt;em&gt;completely&lt;/em&gt;. &lt;strong&gt;Everything else a constructor might do remains subject to change.&lt;/strong&gt; As soon as you think that you’ll never want to change it, your employer will acquire another company, turn it into a new division that supplies your project with software, and you’ll need to change it. To change a constructor, you have to change code: you can’t subclass, you can’t plug in a different implementation of an interface, you can’t override a method, you can’t even invoke a different method. You have to change existing code. Remember that we’re talking about legacy code here: profitable code that you’re afraid to change. So don’t make design decisions that force you to change code that you’re afraid to change. Really.
&lt;/p&gt;
&lt;h2 id=&quot;fine-what-do-i-do-now&quot;&gt;Fine! What Do I Do Now?&lt;/h2&gt;
&lt;p&gt;You can start by introducing &lt;em&gt;named constructors&lt;/em&gt;, which are class-level (&lt;code&gt;static&lt;/code&gt;) functions that instantiate objects.&lt;/p&gt;
&lt;aside&gt;
&lt;strong&gt;Please stop calling these things &lt;em&gt;factories&lt;/em&gt;&lt;/strong&gt;. This causes confusion. A &lt;em&gt;Factory&lt;/em&gt; creates objects while hiding the exact class it has instantiated.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; This means, for example, that it chooses an implementation to instantiate, but returns the object through a reference to the interface type. If you know exactly which class it’s returning, then please call it a &lt;em&gt;creation method&lt;/em&gt; or a &lt;em&gt;named constructor&lt;/em&gt;.
&lt;/aside&gt;
&lt;p&gt;You can introduce a named constructor quite easily. Many refactoring browsers do this automatically. (IntelliJ IDEA frustratingly calls this refactoring “Replace Constructor with Factory Method…”, while Eclipse also frustratingly calls it “Introduce Factory…”.) Even if you don’t use an automated refactoring, you’ll find it relatively easy.&lt;/p&gt;
&lt;p&gt;I’ll start with this debilitating constructor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Game() {
    gameReport = new GameReport() {
        @Override
        public void report(String message) {
            System.out.println(message);
        }
    };

    for (int i = 0; i &amp;lt; 50; i++) {
        popQuestions.addLast(&amp;quot;Pop Question &amp;quot; + i);
        scienceQuestions.addLast((&amp;quot;Science Question &amp;quot; + i));
        sportsQuestions.addLast((&amp;quot;Sports Question &amp;quot; + i));
        rockQuestions.addLast(createRockQuestion(i));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks harmless, but give it a few months. Moreover, I didn’t want to scare you off. I follow these steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Copy all the code into a new class-level function on the same class. Temporarily make fields more visible if you need to.&lt;/li&gt;
&lt;li&gt;Migrate clients to use the new named constructor.&lt;/li&gt;
&lt;li&gt;Add each assigned field to the constructor as a parameter.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;after-step-1&quot;&gt;After Step 1&lt;/h3&gt;
&lt;p&gt;This new code duplicates the constructor, so don’t stop here. I don’t yet know what this named constructor &lt;em&gt;actually does&lt;/em&gt;, so I’ve given it the mechanical name &lt;code&gt;newGame&lt;/code&gt;. I don’t like this name, but I expect to rename it soon.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Game newGame() {
    Game game = new Game();

    game.gameReport = new GameReport() {
        @Override
        public void report(String message) {
            System.out.println(message);
        }
    };

    for (int i = 0; i &amp;lt; 50; i++) {
        game.popQuestions.addLast(&amp;quot;Pop Question &amp;quot; + i);
        game.scienceQuestions.addLast((&amp;quot;Science Question &amp;quot; + i));
        game.sportsQuestions.addLast((&amp;quot;Sports Question &amp;quot; + i));
        game.rockQuestions.addLast(createRockQuestion(i));
    }

    return game;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to write this code, I had to change &lt;code&gt;createRockQuestion()&lt;/code&gt; to be class-level (&lt;code&gt;static&lt;/code&gt;). Unexpectedly, only the &lt;code&gt;Game&lt;/code&gt; constructor used this method, so I had no obstacles to making this method class-level.&lt;/p&gt;
&lt;h3 id=&quot;after-step-2&quot;&gt;After Step 2&lt;/h3&gt;
&lt;p&gt;Well, you can imagine. I don’t have to show you all the instances of &lt;code&gt;new Game()&lt;/code&gt; turned into &lt;code&gt;Game.newGame()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;after-step-3&quot;&gt;After Step 3&lt;/h3&gt;
&lt;p&gt;I did this in a few microsteps. My strategy involves moving &lt;code&gt;new Game()&lt;/code&gt; down to the bottom of the named constructor. Most named constructors do all the interesting work, assign the results to the new instance through its conventional constructor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Game(GameReport gameReport) {
    this.gameReport = gameReport;
}

public static Game newGame() {
    GameReport gameReport = new GameReport() {
        @Override
        public void report(String message) {
            System.out.println(message);
        }
    };

    Game game = new Game(gameReport);

    for (int i = 0; i &amp;lt; 50; i++) {
        game.popQuestions.addLast(&amp;quot;Pop Question &amp;quot; + i);
        game.scienceQuestions.addLast((&amp;quot;Science Question &amp;quot; + i));
        game.sportsQuestions.addLast((&amp;quot;Sports Question &amp;quot; + i));
        game.rockQuestions.addLast(createRockQuestion(i));
    }

    return game;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I build up the first list of questions, then assign it through the constructor. I can foresee having to do the same thing four times, so I use my usual strategy: do the first one, then do the second one, then do the rest.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Game(GameReport gameReport, LinkedList&amp;lt;String&amp;gt; popQuestions) {
    this.gameReport = gameReport;
    this.popQuestions = popQuestions;
}

public static Game newGame() {
    GameReport gameReport = new GameReport() {
        @Override
        public void report(String message) {
            System.out.println(message);
        }
    };

    LinkedList&amp;lt;String&amp;gt; popQuestions = new LinkedList&amp;lt;String&amp;gt;();
    for (int i = 0; i &amp;lt; 50; i++) {
        popQuestions.addLast(&amp;quot;Pop Question &amp;quot; + i);
    }

    Game game = new Game(gameReport, popQuestions);

    for (int i = 0; i &amp;lt; 50; i++) {
        game.scienceQuestions.addLast((&amp;quot;Science Question &amp;quot; + i));
        game.sportsQuestions.addLast((&amp;quot;Sports Question &amp;quot; + i));
        game.rockQuestions.addLast(createRockQuestion(i));
    }

    return game;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the second…&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Game(GameReport gameReport, LinkedList&amp;lt;String&amp;gt; popQuestions, LinkedList&amp;lt;String&amp;gt; scienceQuestions) {
    this.gameReport = gameReport;
    this.popQuestions = popQuestions;
    this.scienceQuestions = scienceQuestions;
}

public static Game newGame() {
    GameReport gameReport = new GameReport() {
        @Override
        public void report(String message) {
            System.out.println(message);
        }
    };

    LinkedList&amp;lt;String&amp;gt; popQuestions = new LinkedList&amp;lt;String&amp;gt;();
    LinkedList&amp;lt;String&amp;gt; scienceQuestions = new LinkedList&amp;lt;String&amp;gt;();
    for (int i = 0; i &amp;lt; 50; i++) {
        popQuestions.addLast(&amp;quot;Pop Question &amp;quot; + i);
        scienceQuestions.addLast((&amp;quot;Science Question &amp;quot; + i));
    }

    Game game = new Game(gameReport, popQuestions, scienceQuestions);

    for (int i = 0; i &amp;lt; 50; i++) {
        game.sportsQuestions.addLast((&amp;quot;Sports Question &amp;quot; + i));
        game.rockQuestions.addLast(createRockQuestion(i));
    }

    return game;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…and by now I feel confident enough to change the rest.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public Game(GameReport gameReport, LinkedList&amp;lt;String&amp;gt; popQuestions, LinkedList&amp;lt;String&amp;gt; scienceQuestions, LinkedList&amp;lt;String&amp;gt; sportsQuestions, LinkedList&amp;lt;String&amp;gt; rockQuestions) {
    this.gameReport = gameReport;
    this.popQuestions = popQuestions;
    this.scienceQuestions = scienceQuestions;
    this.sportsQuestions = sportsQuestions;
    this.rockQuestions = rockQuestions;
}

public static Game newGame() {
    GameReport gameReport = new GameReport() {
        @Override
        public void report(String message) {
            System.out.println(message);
        }
    };

    LinkedList&amp;lt;String&amp;gt; popQuestions = new LinkedList&amp;lt;String&amp;gt;();
    LinkedList&amp;lt;String&amp;gt; scienceQuestions = new LinkedList&amp;lt;String&amp;gt;();
    LinkedList&amp;lt;String&amp;gt; sportsQuestions = new LinkedList&amp;lt;String&amp;gt;();
    LinkedList&amp;lt;String&amp;gt; rockQuestions = new LinkedList&amp;lt;String&amp;gt;();
    for (int i = 0; i &amp;lt; 50; i++) {
        popQuestions.addLast(&amp;quot;Pop Question &amp;quot; + i);
        scienceQuestions.addLast((&amp;quot;Science Question &amp;quot; + i));
        sportsQuestions.addLast((&amp;quot;Sports Question &amp;quot; + i));
        rockQuestions.addLast(createRockQuestion(i));
    }

    return new Game(gameReport, popQuestions, scienceQuestions, sportsQuestions, rockQuestions);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By now I think I understand what this named constructor is doing. I can rename it from &lt;code&gt;newGame&lt;/code&gt; (accurate but vague) to &lt;code&gt;newConsoleReportingDummyGame&lt;/code&gt;, because, let’s face it, those questions look like placeholders just for testing.&lt;/p&gt;
&lt;p&gt;Hey! The questions look like placeholders just for testing, but the &lt;code&gt;GameReporter&lt;/code&gt; seems intended for production use. We should probably just split that behavior apart.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And now we can.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And that’s the point.&lt;/strong&gt;&lt;/p&gt;
&lt;aside&gt;
By the way… we should probably introduce a &lt;em&gt;Parameter Object&lt;/em&gt; for the four sets of questions. That would leave a simple, clear constructor &lt;code&gt;Game(GameReporter, QuestionDeck)&lt;/code&gt;. The resulting constructor might even reveal its own intent well enough that we can get rid of our named constructor.
&lt;/aside&gt;
&lt;h2 id=&quot;the-underlying-design-principle&quot;&gt;The Underlying Design Principle&lt;/h2&gt;
&lt;p&gt;Introducing a named constructor has highlighted a dependency problem: the constructor knew too much about where its data was coming from. This bound the &lt;code&gt;Game&lt;/code&gt; object to a single context, and so for example, if we had to track down a bug related to asking the tenth question, then we would be forced to play a game that moved turn by turn to the tenth question in an arbitrary category. Click. Click. Click. This seems risky and invites failure.&lt;/p&gt;
&lt;p&gt;The constructor violated the &lt;a href=&quot;#dip&quot;&gt;Dependency Inversion Principle&lt;/a&gt;, and introducing a named constructor moved details up the call stack towards the client, leaving behind parameters that we can easily change in order to more easily explore &lt;code&gt;Game&lt;/code&gt;’s behavior. Now if we have a problem asking the tenth question, we can pass in a deck with a single question and figure out what happens.&lt;/p&gt;
&lt;p&gt;This doesn’t solve &lt;em&gt;every&lt;/em&gt; design problem in &lt;code&gt;Game&lt;/code&gt;, but I can only take one step at a time.&lt;/p&gt;
&lt;h2 id=&quot;a-quick-summary&quot;&gt;A Quick Summary&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I want constructors &lt;em&gt;only&lt;/em&gt; to initialize new instances to a “rational” state, so I move more interesting code into named constructors.&lt;/li&gt;
&lt;li&gt;Now that I have to give this construction behavior a name, cohesion and dependency problems become explicit and obvious.&lt;/li&gt;
&lt;li&gt;Now that I have identified explicit, obvious design problems, I can decide how and when to improve the design.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a pleasant side effect, testing the affected code becomes much easier. If you care about that kind of thing.&lt;/p&gt;
&lt;h2 id=&quot;one-more-thing&quot;&gt;One More Thing&lt;/h2&gt;
&lt;p&gt;If you’d like one simple rule of thumb to follow:&lt;/p&gt;
&lt;p class=&quot;instruction&quot;&gt;
Don’t let a constructor invoke an instance method on the instance that it’s in the process of creating.
&lt;/p&gt;
&lt;p&gt;If you found yourself wanting to do this, then you have two responsibilities in the same place. (Why? Think about it.)&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Erik Dietrich, &lt;a href=&quot;https://link.jbrains.ca/1tC0DRV&quot;&gt;&lt;em&gt;Beware the Bloated Constructor&lt;/em&gt;&lt;/a&gt;. Erik’s article triggered my writing this one. He summarizes neatly the toll that a debilitating constructor takes.&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;programming-by-coincidence&quot; /&gt;Andrew Hunt and Dave Thomas, &lt;a href=&quot;https://link.jbrains.ca/WNg8Se&quot;&gt;&lt;em&gt;The Pragmatic Programmer&lt;/em&gt;&lt;/a&gt;. Item 31 in this classic book is &lt;em&gt;Programming By Coincidence&lt;/em&gt;, in which the authors paint a beautiful picture of just how slowly and deliberately the programmer has to work when encountering code such as debilitating constructors.&lt;/p&gt;
&lt;p&gt;Erich Gemma and others, &lt;a href=&quot;https://link.jbrains.ca/11ATEqK&quot;&gt;&lt;em&gt;Design Patterns&lt;/em&gt;&lt;/a&gt;. The first book I ever bought as hypertext, and a book truly designed for it. It explains what makes a &lt;em&gt;factory&lt;/em&gt; a factory. Please don’t just look at the class diagrams. Please read the “Drawbacks and Alternatives” sections.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;“Demystifying the Dependency Inversion Principle”&lt;/a&gt;. A handful of ways to approach and understand the Dependency Inversion Principle.&lt;/p&gt;
&lt;p&gt;Miko Hevery, &lt;a href=&quot;https://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/&quot;&gt;“Flaw: Constructor Does Real Work”&lt;/a&gt;. Another article in a similar vein from 2008.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;The Wikipedia entry about the &lt;a href=&quot;https://link.jbrains.ca/1rkGoks&quot;&gt;factory method pattern&lt;/a&gt; summarizes the pattern quite well—or it least it did as of this writing.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 23 Mar 2015 03:30:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/your-constructors-are-completely-irrational</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/your-constructors-are-completely-irrational</guid>
        
        
      </item>
    
      <item>
        <title>A Real-Life Contract Test</title>
        <description>&lt;p&gt;For years I’ve written about contract tests, and most notably have never had any clear examples of them to share with you. I’d like to change that today.&lt;/p&gt;
&lt;p&gt;I’m sharing this with you as a &lt;strong&gt;rough cut&lt;/strong&gt;, meaning that I haven’t yet taken the time to seriously edit this, nor add much explanation. I feel tired just now, so I want to stop, but at the same time, my loyal readers deserve to see a real example.&lt;/p&gt;
&lt;p&gt;I’ve spent the last few days messing around with the Atom text editor, writing a package for it that calculates some basic text document statistics. I started with &lt;a href=&quot;https://github.com/cjoh/status-stats&quot;&gt;https://github.com/cjoh/status-stats&lt;/a&gt;, but noticed that this had fallen rather seriously out of date, and… well, I’ll spare you the story. I’m here now.&lt;/p&gt;
&lt;h2 id=&quot;get-to-the-point&quot;&gt;Get To The Point!&lt;/h2&gt;
&lt;p&gt;The text statistics library that &lt;span class=&quot;citation&quot; data-cites=&quot;cjoh&quot;&gt;@cjoh&lt;/span&gt; used doesn’t count words correctly. (I’m working in &lt;a href=&quot;https://www.coffeescript.org&quot;&gt;CoffeeScript&lt;/a&gt;.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TextStatistics = require(&amp;quot;text-statistics&amp;quot;)

describe &amp;quot;The textStatistics API&amp;quot;, -&amp;gt;
  describe &amp;quot;happy path example&amp;quot;, -&amp;gt;
    it &amp;quot;sure as hell doesn&amp;#39;t count words&amp;quot;, -&amp;gt;
      textStatistics = new TextStatistics(&amp;quot;What the fuck&amp;quot;)
      expect(textStatistics.text).toBe(&amp;quot;What the fuck.&amp;quot;) # Works for me...
      expect(textStatistics.wordCount()).toBe(4) # I don&amp;#39;t even...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whatever.&lt;/p&gt;
&lt;p&gt;I decided to look for a library that counts words correctly. I found one called &lt;code&gt;words.js&lt;/code&gt;. (I could tell you a whole story here, but I won’t.) It seems to count words correctly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require(&amp;quot;words.js&amp;quot;)

describe &amp;quot;The Words API&amp;quot;, -&amp;gt;
  describe &amp;quot;counting words&amp;quot;, -&amp;gt;
    # CONTRACT
    # Words.count always answers a valid Number, even
    # when it encounters invalid input.
    # When the input is text, then .count appears to
    # answer the correct count of the words.
    # When the input is not text, then .count returns
    # an arbitrary Number, often 0.
    countWords = (text) -&amp;gt;
      new Words(text).count

    it &amp;quot;counts words, maybe&amp;quot;, -&amp;gt;
      expect(countWords(&amp;quot;There are four words!&amp;quot;)).toBe(4)

    it &amp;quot;counts the empty string!!!111!1!1!&amp;quot;, -&amp;gt;
      expect(countWords(&amp;quot;&amp;quot;)).toBe(0)

    it &amp;quot;gracefully handles null&amp;quot;, -&amp;gt;
      expect(countWords(null)).toBe(0)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I wrote more, but you get the idea. When I felt confident that &lt;code&gt;words.js&lt;/code&gt; counts words correctly, I decided to jump to the key question: &lt;em&gt;What contract does my package need with the thing that counts words?&lt;/em&gt; I decided on this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;countWords&lt;/code&gt; turns text into a number&lt;/li&gt;
&lt;li&gt;&lt;code&gt;countWords&lt;/code&gt;’ return value represents the number of words in its input text, as long as the input consists of text&lt;/li&gt;
&lt;li&gt;if the input is not text, then &lt;code&gt;countWords&lt;/code&gt; can return any number it likes, as long as it returns a number, and nothing else, and doesn’t throw an error&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This contract implies two things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;The invoker can’t tell whether &lt;code&gt;countWords&lt;/code&gt; has returned an accurate count of words, because &lt;code&gt;countWords&lt;/code&gt; doesn’t signal invalid input; &lt;strong&gt;therefore&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The invoker shouldn’t send &lt;code&gt;countWords&lt;/code&gt; invalid input.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Fortunately as long as my package uses Atom correctly, this won’t cause a problem. More importantly, my package will never cause Atom to blow up. In the worst case, it shows strange results on the status bar.&lt;/p&gt;
&lt;h2 id=&quot;contract-tests-dammit&quot;&gt;Contract Tests, Dammit!&lt;/h2&gt;
&lt;p&gt;I found &lt;a href=&quot;https://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/&quot;&gt;this nice article&lt;/a&gt; on shared examples for Jasmine, remembered how I used to write &lt;a href=&quot;https://duckduckgo.com/?q=parameterized+test+case+pattern&quot;&gt;parameterized test cases&lt;/a&gt; in Ruby, and eventually came up with this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# countWords :: text -&amp;gt; number
theContractForCountingWords = (countWords) -&amp;gt;
  describe &amp;quot;The contract for Counting Words&amp;quot;, -&amp;gt;
    describe &amp;quot;counting words accurately for valid input&amp;quot;, -&amp;gt;
      it &amp;quot;counts words for a simple text&amp;quot;, -&amp;gt;
        expect(countWords(&amp;quot;A very simple text.&amp;quot;)).toBe(4)

      it &amp;quot;counts words for a multiline text&amp;quot;, -&amp;gt;
        expect(countWords(&amp;quot;&amp;quot;&amp;quot;
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Nullam eros urna, dictum quis magna a, bibendum porttitor
  ipsum. Donec ullamcorper ante ac eros auctor commodo.
  Pellentesque eu nulla in est congue porttitor. Phasellus
  quis pretium eros, eu sagittis nisi. Quisque at scelerisque
  metus. Etiam mollis velit nec mi malesuada rutrum. Maecenas
  in nibh et est suscipit bibendum quis et ligula. Sed
  scelerisque luctus justo. Integer eget eros aliquam, ultrices
  lorem ut, ornare metus. Duis vel varius felis.
  &amp;quot;&amp;quot;&amp;quot;)).toBe(77)

      it &amp;quot;handles the empty string&amp;quot;, -&amp;gt;
        expect(countWords(&amp;quot;&amp;quot;)).toBe(0)

      it &amp;quot;handles non-empty whitespace&amp;quot;, -&amp;gt;
        expect(countWords(&amp;quot;\t\n\r \t\n \n\n\r&amp;quot;)).toBe(0)

    describe &amp;quot;error paths, where it must not blow up&amp;quot;, -&amp;gt;
      @specialCases =
        &amp;quot;null&amp;quot;: null
        &amp;quot;NaN&amp;quot;: NaN
        &amp;quot;an empty object&amp;quot;: {}
        &amp;quot;an empty array&amp;quot;: []
        &amp;quot;a non-empty object&amp;quot;: {a: 1, b: 2, c: &amp;quot;hello&amp;quot; }
        &amp;quot;a non-empty array&amp;quot;: [1, 2, 3, &amp;quot;hello&amp;quot;]

      @checks = (name, inputValue) -&amp;gt;
        it &amp;quot;does not throw an error when its input is #{name}&amp;quot;, -&amp;gt;
          expect( -&amp;gt;
            countWords(inputValue)
          ).not.toThrow()

        it &amp;quot;returns a number when its input is #{name}&amp;quot;, -&amp;gt;
          expect(typeof countWords(inputValue)).toBe(&amp;quot;number&amp;quot;)

      @checks(name, inputValue) for name, inputValue of @specialCases&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can implement the count words interface correctly (passing the contract tests) by simply delegating to &lt;code&gt;words.js&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require(&amp;quot;words.js&amp;quot;)

countWordsWithWordsJs = (text) -&amp;gt;
  new Words(text).count

describe &amp;quot;Counting Words with Words.js&amp;quot;, -&amp;gt;
  theContractForCountingWords(countWordsWithWordsJs)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can freely use &lt;code&gt;words.js&lt;/code&gt; in any object that exposes &lt;code&gt;countWords&lt;/code&gt;, then show that that object respects the contract of &lt;code&gt;countWords&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require(&amp;quot;words.js&amp;quot;)

class CountWordsWithWordsJs
  countWords = (text) -&amp;gt;
    new Words(text).count

describe &amp;quot;Counting Words with Words.js&amp;quot;, -&amp;gt;
  theContractForCountingWords(new CountWordsWithWordsJs().countWords)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My next step involves exploring and clarifying the contract for two more little microfeatures before putting the whole thing together and shipping it.&lt;/p&gt;
&lt;h2 id=&quot;shout-out&quot;&gt;Shout Out&lt;/h2&gt;
&lt;p&gt;I would like to thank &lt;a href=&quot;https://github.com/kevinsawicki&quot;&gt;Kevin Sawicki&lt;/a&gt; for treating me so nicely as I made my first few microcontributions to Atom. Kevin, you have made me feel very welcome in your community.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://vimeo.com/80533536&quot;&gt;“Integrated Tests are a Scam”&lt;/a&gt;. An hour-long talk, so save it for when you have the time. It presents how contract tests fit into my practice as a programmer.&lt;/p&gt;
&lt;p&gt;c2.com Wiki Community, &lt;a href=&quot;https://www.c2.com/cgi/wiki?AbstractTestCases&quot;&gt;“Abstract Test Cases”&lt;/a&gt; When we first discussed contract tests, we called them “Abstract Test Cases”, because we name things like programmers. I remember writing my example sometime in 2000. Of note: “This kind of test case ensures that concrete classes do not violate the contracts of their superclasses.”&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/1AHD22G&quot;&gt;JUnit Recipes&lt;/a&gt; Recipe 2.6 “Test an interface” shows an early example of a contract test for Java’s &lt;code&gt;Iterator&lt;/code&gt; interface.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/in-brief-contract-tests&quot;&gt;“In Brief: Contract Tests”&lt;/a&gt; The first time I can remember referring to them as “contract tests”.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/who-tests-the-contract-tests&quot;&gt;“Who Tests the Contract Tests?”&lt;/a&gt; How to keep contract tests in correspondence with implementation details tests.&lt;/p&gt;
&lt;p&gt;Davis W. Frank, &lt;a href=&quot;https://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/&quot;&gt;“DRYing Up Jasmine Specs with Shared Behavior”&lt;/a&gt;. Obviously, exactly the way I do it in Ruby.&lt;/p&gt;
&lt;p&gt;Web Search, &lt;a href=&quot;https://duckduckgo.com/?q=parameterized+test+case+pattern&quot;&gt;“Parameterized Test Case Pattern”&lt;/a&gt;. Read lots on the subject. We’ve been doing this for a long time.&lt;/p&gt;
</description>
        <pubDate>Thu, 05 Mar 2015 04:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-real-life-contract-test</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-real-life-contract-test</guid>
        
        
      </item>
    
      <item>
        <title>You Have To Know When To Stop</title>
        <description>&lt;p&gt;After one of the mob programming sessions I did with &lt;a href=&quot;https://www.rubysteps.com&quot;&gt;RubySteps&lt;/a&gt; last year, a viewer singled out this as a valuable piece of advice:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One of the most important things that a programmer must learn how to do is to stop when they get to the end.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I remember the first time I encountered this issue: in Steve McConnell’s excellent book &lt;a href=&quot;https://link.jbrains.ca/1tU7uTW&quot;&gt;&lt;em&gt;Rapid Development&lt;/em&gt;&lt;/a&gt;, which I remember reading in 1997. (Wow! I should read it again.) He referred to “gold-plating” as one of his Classic Development Mistakes. You might immediately think, &lt;em&gt;Uh… &lt;a href=&quot;https://link.jbrains.ca/bob-newhart-stop-it&quot;&gt;stop it!&lt;/a&gt;&lt;/em&gt;, but until then I hadn’t realized just how pervasively programmers in particular tended to do this. They would continue working on something, even though they’d solved the underlying problem. This sounded utterly insane to me. Suddenly, I saw it everywhere. I noticed when others did it. (They loved that.) I noticed when I did it. I didn’t really understand why.&lt;/p&gt;
&lt;p&gt;When I started practising test-first programming (and later test-driven development), this problem slowly disappeared—at least for a while. (Read on; you’ll see why.) For years, one of my IBM office mates challenged me to justify writing the tests first. He argued that as long as he wrote his tests and production code in tiny cycles, it didn’t much matter which he wrote first. For years, I never had a good answer for him. Of course, now that I do, I have no idea where to find him.&lt;/p&gt;
&lt;h2 id=&quot;write-until-you-get-to-the-end-then-stop&quot;&gt;Write Until You Get To The End, Then Stop&lt;/h2&gt;
&lt;p&gt;Among the microbenefits of writing tests first: knowing when to stop. I approach test-driven development roughly like this:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Write a failing test that describes a very small bit of new behavior.&lt;/li&gt;
&lt;li&gt;Run the tests to watch the new test fail.&lt;/li&gt;
&lt;li&gt;Write just enough production code to make the tests pass.&lt;/li&gt;
&lt;li&gt;Run the tests to watch all the tests pass.&lt;/li&gt;
&lt;li&gt;Now that I have a solid pool of change detectors, try to improve the design, usually following the &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Simple Design Dynamo&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All these steps help me write better code, but I want to focus on just two of these steps.&lt;/p&gt;
&lt;p&gt;First, we have the act of writing a failing list, which describes when to stop. You can’t know when to stop if you haven’t thought about when you &lt;em&gt;should&lt;/em&gt; stop. I imagine that programmers gold-plate in part because they don’t really understand the goal behind their task. They might not even know the goal behind a microtask on the way to completing their larger task, &lt;em&gt;even though they themselves have divided their task into microtasks&lt;/em&gt;. Amazing, isn’t it? They might have a vague idea of the steps, but writing tests encourages the programmer to articulate very clearly the goal of the next step. By doing this, one can’t help but know exactly what “there” looks like, so as to stop when arriving “there”.&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;When I see the green bar, I know I’ve arrived “there”.&quot;&gt;&lt;/span&gt; In addition to knowing where to stop, we need to know when we’ve got “there”. For this purpose, the step “write &lt;strong&gt;just enough&lt;/strong&gt; production code” matters most. When I write tests first, I find it much easier to judge when I’ve written just enough production code, because the new tests now passes and I haven’t broken anything that used to work. When I see the green bar, I know I’ve arrived “there”. Doing this brings more benefits than only that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I know when to stop writing code right now related to the current task/feature/behavior.&lt;/li&gt;
&lt;li&gt;I train myself in general to stop writing code once I’ve written enough.&lt;/li&gt;
&lt;li&gt;I train myself to think about what it would mean to have written enough code, so that I get better at spotting it when it happens.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It might seem like overkill to you, but remember: programmers famously tend to gold-plate, and so any technique that helps a programmer &lt;a href=&quot;#quick-win&quot;&gt;ingrain the habit&lt;/a&gt; of stopping will probably help. Test-first programming fits the bill.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Imagine that you had on your computer a red flashing light that signaled &lt;em&gt;that’s enough&lt;/em&gt; as you wrote code.&lt;/strong&gt; When you saw it flash, you could stop, then go on to the next microtask. Wouldn’t that help you finish your work sooner? Wouldn’t that help you question whether you need to do what you have in mind next? Wouldn’t that help you avoid unnecessary work in the first place? It sounds great to me! Writing tests first gives me exactly that, so I do it even to this day, lest I fall back to gold-plating.&lt;/p&gt;
&lt;h2 id=&quot;danger-gold-plating-the-design&quot;&gt;Danger: Gold-Plating the Design&lt;/h2&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;I love refactoring because I never have to stop.&quot;&gt;&lt;/span&gt; The Universe, however, in its desire to respect the Law of Conservation of Irony, intervenes. Although I write the tests first in order to tell me when to stop writing code, &lt;strong&gt;the refactoring step gives me a new opportunity to flex my gold-plating muscles&lt;/strong&gt;. I love refactoring because I never have to stop. I can always find something more to improve. I can go around the &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;Simple Design Dynamo&lt;/a&gt; again and again and again… try to stop me!
&lt;/p&gt;
&lt;p&gt;Now you see why I pointed out more benefits than simply “I know when to stop writing code for the current microtask”. Knowing that the programmer mindset tends to lean towards gold-plating in general, I continue to write tests first in order to &lt;strong&gt;train myself to remain aware of my own tendency towards gold-plating&lt;/strong&gt;. As a result, I do it less often, and in a variety of situations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I learn to refactor just enough to keep new features flowing without turning modularity into a means unto itself. I don’t want to turn clean code into a fetish.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I learn to build just enough features to keep new customers flowing, rather than trying to deliver the perfect product.&lt;/li&gt;
&lt;li&gt;I learn to edit just enough in order to convey my ideas clearly, rather than trying to turn my work into literature.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could probably find more, but that will do for now. What do you do in order to counter your own tendency towards gold-plating? It might have nothing to do with code. I’d love to learn your secrets either at &lt;a href=&quot;https://tell.jbrains.ca&quot;&gt;tell.jbrains.ca&lt;/a&gt; or in the comments.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;“Putting an Age-Old Battle to Rest”&lt;/a&gt;. The article that turns the four elements of simple design into the Simple Design Dynamo.&lt;/p&gt;
&lt;p&gt;Steve McConnell, &lt;a href=&quot;https://link.jbrains.ca/1tU7uTW&quot;&gt;&lt;em&gt;Rapid Development&lt;/em&gt;&lt;/a&gt;. One of the pre-agile books that had a significant impact on how I thought about professional software development.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;quick-win&quot;&gt;&lt;/a&gt;J. B. Rainsberger, &lt;a href=&quot;https://blog.jbrains.ca/permalink/change-your-life-one-habit-at-a-time&quot;&gt;“Change Your Life One Habit At A Time”&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I only refactor &lt;a href=&quot;/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;in order to reduce volatility in the marginal cost of features&lt;/a&gt;. Don’t you?&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 15 Feb 2015 11:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/you-have-to-know-when-to-stop</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/you-have-to-know-when-to-stop</guid>
        
        
      </item>
    
      <item>
        <title>Learning Tests for POSTing Email from Mailgun</title>
        <description>&lt;p&gt;I had intended to write a nice article showing a concrete example of &lt;em&gt;learning tests&lt;/em&gt; in action, then something wonderful happened: all the code disappeared.&lt;/p&gt;
&lt;h2 id=&quot;the-situation&quot;&gt;The Situation&lt;/h2&gt;
&lt;p&gt;I love &lt;a href=&quot;https://www.typeform.com&quot;&gt;Typeform&lt;/a&gt;, especially because it integrates with &lt;a href=&quot;https://www.stripe.com&quot;&gt;Stripe&lt;/a&gt; for processing payments. Sadly, Typeform does not allow my customer to pay-what-they-think-it-was-worth unless I anchor them by presenting a handful of price options, similar to what you see here.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/LearningTestsForPostingEmailFromMailgun/TheClosestWeCanGetToPayWhatYouWant.png&quot; /&gt;
&lt;figcaption&gt;
Not the way I want to let my customers choose the amount they wish to pay. How many buttons should I give them?
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;the-plan-of-attack&quot;&gt;The Plan of Attack&lt;/h2&gt;
&lt;p&gt;After reviewing my options, I settled on letting a customer enter the amount they want to pay in a Typeform form, which will send an email to a custom application that responds with a link to a Stripe checkout form for the amount they chose. It feels a little convoluted, but it will work. I know how to create the Stripe checkout and I know how to create the Typeform form, but I have not handled incoming email with Ruby and Sinatra and Heroku before, so I need to learn that.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/LearningTestsForPostingEmailFromMailgun/ForwardingEmailFromMailgunToSinatra.png&quot; /&gt;
&lt;figcaption&gt;
The Architecture Diagram
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;an-hour-of-pointless-coding-later&quot;&gt;An Hour of Pointless Coding Later…&lt;/h2&gt;
&lt;p&gt;After writing code (and documenting what I did so that I could publish it for you to read), I found out that I didn’t need to do any of it. Instead, I could use existing tools to learn what I needed to know. Specifically, I needed to know the format of what Mailgun will forward to my Sinatra application’s &lt;code&gt;POST&lt;/code&gt; handler.&lt;/p&gt;
&lt;p&gt;In reading &lt;a href=&quot;https://link.jbrains.ca/1oMOCHt&quot;&gt;Mailgun’s REST API documentation&lt;/a&gt;, I discovered a wonderful tool: &lt;a href=&quot;https://bin.mailgun.net/&quot;&gt;https://bin.mailgun.net/&lt;/a&gt;.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; When you visit bin.mailgun.net, you receive a URL to which you can send requests and see the results all nicely formatted for you.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/LearningTestsForPostingEmailFromMailgun/SampleOutputBinMailgunNet.png&quot; /&gt;
&lt;figcaption&gt;
Pretty, no?
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;With this, I have documentation of one half of the contract between Mailgun and my Sinatra application, namely the contents of the &lt;code&gt;POST&lt;/code&gt; request representing the incoming email, but what about the contract of the response? I found this in the documentation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For Route POSTs, Mailgun listens for the following codes from your server and reacts accordingly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If Mailgun receives a 200 (Success) code it will determine the webhook POST is successful and not retry.&lt;/li&gt;
&lt;li&gt;If Mailgun receives a 406 (Not Acceptable) code, Mailgun will determine the POST is rejected and not retry.&lt;/li&gt;
&lt;li&gt;For any other code, Mailgun will retry POSTing according to the schedule below for Webhooks other than the delivery notification.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your application is unable to process the webhook request but you do not return a 406 error code, Mailgun will retry (other than for delivery notification) during 8 hours at the following intervals before stop trying: 10 minutes, 10 minutes, 15 minutes, 30 minutes, 1 hour, 2 hour and 4 hours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Excellent. I have enough information about the contract between Mailgun and a &lt;code&gt;POST&lt;/code&gt; handler that I can design my Sinatra application. I can even test-drive it! (Don’t mind the diagram. I promise that I’ll return the appropriate HTTP status code when things go wrong.)&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/LearningTestsForPostingEmailFromMailgun/MailgunSinatraIntegrationDesignSketch.png&quot; /&gt;
&lt;figcaption&gt;
I loves me some Plain Ruby!
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;uh-where-are-the-learning-tests&quot;&gt;Uh… Where Are the Learning Tests?&lt;/h2&gt;
&lt;p&gt;I ran them manually. I suppose I could have automated them, but I don’t see the value. If I notice behavior that seems not to conform to the contract I’ve discovered here today, then I’ll fire up RSpec; for now, this will do.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Evidently I could have used &lt;a href=&quot;https://requestbin.com&quot; class=&quot;uri&quot;&gt;https://requestbin.com&lt;/a&gt; for the same purpose.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 26 Oct 2014 21:26:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/learning-tests-for-posting-email-from-mailgun</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/learning-tests-for-posting-email-from-mailgun</guid>
        
        
      </item>
    
      <item>
        <title>IDEA Crashes on Launch on Yosemite</title>
        <description>&lt;p&gt;I upgraded to Mac OS 10.10 Yosemite and something strange happened with my installations of IntelliJ IDEA. They just disappeared. I still don’t know what happened to them. When I tried to reinstall IDEA 13 Community Edition, it crashed on launch.&lt;/p&gt;
&lt;aside&gt;
Evidently, IDEA normally gracefully handles not finding a JRE with which to launch itself; but it didn’t for me, and I still don’t know why. After fixing the situation, IDEA now indeed handles a missing JRE gracefully. My Java SE 6 installation must have found itself in an irrational state.
&lt;/aside&gt;
&lt;p&gt;Fortunately, my Twitter community came to my rescue. I’m sharing my experience here, just to make it easier for those who upgrade after me. I found two solutions.&lt;/p&gt;
&lt;h2 id=&quot;a-risky-solution&quot;&gt;A Risky Solution&lt;/h2&gt;
&lt;p&gt;When I reinstalled Java SE 6 and made it my system Java virtual machine, IDEA 13 (and IDEA 14 beta) launched successfully. I followed these steps.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Install Java SE 6, which &lt;a href=&quot;https://support.apple.com/kb/DL1572&quot;&gt;Apple ships on its own&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;export JAVA_HOME=/usr/libexec/java_home -v &quot;1.6.0&quot;&lt;/code&gt; to your login shell initialization script which, for me, was &lt;code&gt;.zshrc&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This, of course, provides a system-wide solution. It works, but it perpetuates an annoying dependency between IDEA and the state of my operating system. As with any reliance on global variables, it carries certain risk. It made me happy, then, that my Twitter community pointed me towards a more localized solution.&lt;/p&gt;
&lt;h2 id=&quot;a-less-risky-solution&quot;&gt;A Less Risky Solution&lt;/h2&gt;
&lt;p&gt;Thanks to this tweet, I have managed to solve the problem in a less risky fashion.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;https://twitter.com/adymitruk&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;adymitruk&quot;&gt;@adymitruk&lt;/span&gt;&lt;/a&gt; &lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;&lt;/a&gt; You just need to update the Info.plist to use 1.7 or 1.8.
&lt;/p&gt;
— Hadi Hariri (&lt;span class=&quot;citation&quot; data-cites=&quot;hhariri&quot;&gt;@hhariri&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/hhariri/status/523714117530419201&quot;&gt;October 19, 2014&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;I followed these steps.&lt;/p&gt;
&lt;figure&gt;
&lt;a href=&quot;/images/IdeaLaunchJreSetting.png&quot;&gt;&lt;img src=&quot;/images/IdeaLaunchJreSetting.png&quot; alt=&quot;Setting the JRE that launches IDEA&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;
Setting the JRE that launches IDEA
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Duplicate the IDEA .app launcher, so as to keep an old copy with which to test.&lt;/li&gt;
&lt;li&gt;Locate &lt;code&gt;Contents/Info.plist&lt;/code&gt; inside the .app launcher and edit it. (“Show Package Contents” in Finder.)&lt;/li&gt;
&lt;li&gt;Look for the dictionary with key &lt;code&gt;JVMOptions&lt;/code&gt; and find the value corresponding to &lt;code&gt;JVMVersion&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Change this value to &lt;code&gt;1.8*&lt;/code&gt; in order to look for a JRE matching what &lt;code&gt;/usr/libexec/java_home -v &apos;1.8*&apos;&lt;/code&gt; would find.&lt;/li&gt;
&lt;li&gt;Launch the .app and verify that it launches.&lt;/li&gt;
&lt;li&gt;Remove Java SE 6 from the system path. (I &lt;code&gt;tar&lt;/code&gt;d it as a backup, then deleted it from &lt;code&gt;/System/Library/Java/JavaVirtualMachines&lt;/code&gt;.)&lt;/li&gt;
&lt;li&gt;Launch the .app and verify that it still launches.&lt;/li&gt;
&lt;li&gt;Launch the other copy of the .app—still set to expect Java SE 6—and verify that it no longer launches.&lt;/li&gt;
&lt;li&gt;Change the &lt;code&gt;JVMOptions/JVMVersion&lt;/code&gt; to &lt;code&gt;1.7*&lt;/code&gt;, while leaving Java 8 active as the system JRE.&lt;/li&gt;
&lt;li&gt;Launch the .app and verify that it still launches, even though Java SE 7 is not the system JRE.&lt;/li&gt;
&lt;li&gt;Change the &lt;code&gt;JVMOptions/JVMVersion&lt;/code&gt; back to &lt;code&gt;1.8*&lt;/code&gt;, because I want to keep that value.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I much prefer this localized solution, as it breaks the dependency between IDEA and the system JRE.&lt;/p&gt;
&lt;p&gt;Choose whichever solution works better for you. Enjoy!&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;stackoverflow.com, &lt;a href=&quot;https://link.jbrains.ca/1wdoIMX&quot;&gt;“IntelliJ not starting after OS X Yosemite update”&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Oct 2014 09:35:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/idea-crashes-on-launch-on-yosemite</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/idea-crashes-on-launch-on-yosemite</guid>
        
        
      </item>
    
      <item>
        <title>Gaining Confidence in Code that Generates HTML</title>
        <description>&lt;p&gt;How do I gain confidence in code that generates HTML, such as tag libraries or view templates?&lt;/p&gt;
&lt;p&gt;Well, it depends on what I’m trying to do. &lt;!--more--&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Am I learning how an existing tag library works?&lt;/strong&gt; If so, then I create a bare project, install the tag library, use it to generate some HTML, then use something like HTMLUnit&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; (any HTML parser will do) to check the results. This way, I can explore all the features that the tag library has without mixing those tests up with the tests for my project’s core behavior. I can use what I learn from these Learning Tests&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, meaning the &lt;strong&gt;contract of the tag library features that matter to me&lt;/strong&gt;, to write tests for my core behavior that make safe—well, &lt;em&gt;safer&lt;/em&gt;—assumptions about what the tag libraries do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Am I creating my own tag library?&lt;/strong&gt; I typically create custom tags by extracting duplication from HTML, so whatever tests I already have for HTML indirectly test my custom tags. Once I extract enough behavior into a little group of custom tags, then I begin to feel like I have a proper, reusable library&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;, and then I treat it exactly like I do any existing tag library, so this reduces to my answer above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Am I testing other view code that generates HTML, meaning not a tag library?&lt;/strong&gt; In this case, I make sure to separate that code from the rest of the system. In particular, I don’t want to have click-click-click in order to get to the right page so that I can check the resulting HTML. If I have to click-click-click, then I’ve clearly &lt;a href=&quot;https://link.jbrains.ca/1vWUxKA&quot;&gt;violated the Dependency Inversion Principle&lt;/a&gt;, since the view depends on its invoker, the controller.&lt;/p&gt;
&lt;aside&gt;
Please note that automating this click-click-click with something like Selenium doesn’t make this problem go away; it merely makes it easier to tolerate the problem… for a while.
&lt;/aside&gt;
&lt;p&gt;This means finding a way to render my HTML template directly without invoking the rest of the application. How to do this varies from framework to framework, or from library to library. It’s one of the reasons that, way back in the 2000s, I preferred using an HTML template engine like &lt;a href=&quot;https://velocity.apache.org/&quot;&gt;Apache Velocity&lt;/a&gt; over using JSP. I never did figure out how to reliably render a JSP without involving the rest of the web container and its nonsense. Are there any standalone JSP engines now? I don’t know.&lt;/p&gt;
&lt;p&gt;I know that &lt;a href=&quot;https://github.com/rspec/rspec-rails&quot;&gt;RSpec does this well for Rails&lt;/a&gt;. I can simply render a view template with whatever data I desire, and I never have to invoke a controller nor run the rest of the system. Now &lt;em&gt;how&lt;/em&gt; RSpec-Rails does this amounts to killing kittens, but that’s mostly because Rails likes coupling everything to everything else and expects you to like it, too. I try to ignore the mewling of dying kittens as I run my view specs.&lt;/p&gt;
&lt;h2 id=&quot;the-two-key-points&quot;&gt;The Two Key Points&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;To check the HTML that X generates, run X without running the things that invoke X.&lt;/strong&gt; (Dependency Inversion Principle.) This is true for X = JSP processor; X = HTML template engine; X = whatever. Write a test like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;htmlAsString = render(template, dictionaryOfDynamicDataToDisplayOnTemplate)
htmlDocument = htmlParser.parse(htmlAsString)
assert whatever you like about htmlDocument&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you do this, you &lt;strong&gt;describe the contract of the view&lt;/strong&gt;. You can use this information to check that the controller puts the right data in the right view template variables without having to run the controller and view together.&lt;/p&gt;
&lt;p&gt;For example, if you know that your view expects the scripting variable &lt;code&gt;customers&lt;/code&gt; with a collection of &lt;code&gt;Customer&lt;/code&gt; objects, then your controller tests can check that it puts a valid (non-&lt;code&gt;null&lt;/code&gt;) collection of &lt;code&gt;Customer&lt;/code&gt; objects wherever the view rendering engine will look for the scripting variable &lt;code&gt;customers&lt;/code&gt;. In the Spring WebMVC world—and I realize I’m old—this meant the &lt;code&gt;customers&lt;/code&gt; key in the model &lt;code&gt;Map&lt;/code&gt; inside the &lt;code&gt;ModelAndView&lt;/code&gt; object that the controller returns from its &lt;code&gt;handleRequest()&lt;/code&gt; implementation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don’t test a tag library by testing your application&lt;/strong&gt;. If you want to test the tag library, then test it in isolation. This also applies to learning about the tag library by writing Learning Tests for it.&lt;/p&gt;
&lt;p&gt;When you want to use a tag library, you think about which features of it you want to use and how you expect those features to behave. You can probably explore those more thoroughly by not limiting yourself to the exact context in which you plan to use that tag library feature right now. You’ll probably learn more than simply trying to get the current thing working that you want to get working. This helps you better understand which part of the tag library’s contract your application will depend on. You will find this useful, I promise.&lt;/p&gt;
&lt;aside&gt;
Notice that, in what I’ve just written here, you can substitute “tag library” for other generic services like “database driver”.
&lt;/aside&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger and Scott Stirling, &lt;a href=&quot;https://manning.com/rainsberger/&quot;&gt;&lt;em&gt;JUnit Recipes&lt;/em&gt;&lt;/a&gt;. In particular, chapter 12, “Testing Web Components” covers a lot of this ground. Even if you don’t use JUnit, the principles apply.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;“Demystifying the Dependency Inversion Principle”&lt;/a&gt;. A few different ways to think about this principle, as well as what it means for your ability to test your code.&lt;/p&gt;
&lt;p&gt;Michael Feathers, &lt;a href=&quot;https://link.jbrains.ca/jdXMTy&quot;&gt;&lt;em&gt;Working Effectively with Legacy Code&lt;/em&gt;&lt;/a&gt;. Still the classic text on legacy code, in which he discusses characterization tests. Some modern libraries make it easier to write these kinds of tests, like &lt;a href=&quot;https://texttest.org&quot;&gt;TextTest&lt;/a&gt; or &lt;a href=&quot;https://blog.approvaltests.com/&quot;&gt;ApprovalTests&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I know that I’m showing my age here, but I was there when HTMLUnit was born, so I like to mention it every now and then.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Tests that I write to document how a library behaves. When they pass, then I understand what the library does; when they fail, I don’t. Michael Feathers also refers to &lt;em&gt;characterization tests&lt;/em&gt;, which characterize what the code does, rather than specify what we want the code to do.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Reusability happens when we make it happen.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 12 Oct 2014 13:18:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/gaining-confidence-in-code-that-generates-html</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/gaining-confidence-in-code-that-generates-html</guid>
        
        
      </item>
    
      <item>
        <title>Clean Up Those Nasty Junk Drawers</title>
        <description>&lt;p&gt;Almost everyone starts organizing their tests according to the module (or class or object) that they’re testing. If they have a class called &lt;code&gt;Customer&lt;/code&gt;, then they have a test case class called &lt;code&gt;CustomerTest&lt;/code&gt; and put all the tests for &lt;code&gt;Customer&lt;/code&gt; into this one bundle (module, class, &lt;code&gt;describe&lt;/code&gt; block, whatever you call it).&lt;/p&gt;
&lt;p&gt;Don’t stop here.&lt;/p&gt;
&lt;p&gt;If you continue to add &lt;em&gt;all&lt;/em&gt; your &lt;code&gt;Customer&lt;/code&gt; tests to &lt;code&gt;CustomerTest&lt;/code&gt;, then you’ll certainly judge it as “too big” after a while. Even if you don’t, you’ll notice some patterns in the names of the tests themselves.&lt;/p&gt;
&lt;aside&gt;
If you work with libraries like Spock or RSpec that let you name tests with arbitrary text, then you might not notice these patterns as easily, or the duplication might seem “more natural” in natural language. Don’t let that fool you into thinking that you haven’t duplicated concepts in your code!
&lt;/aside&gt;
&lt;p&gt;You’ve almost certainly noticed a pattern in the names of some of your tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testAdd_EmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testAdd_NonemptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testAdd_ListAtCapacity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testAdd_DuplicateItem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testContains_ItemFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testContains_ItemNotFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testContains_DuplicateItem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testSize_EmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testSize_NonEmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty_EmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty_NonEmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf_ItemFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf_ItemNotFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testTrimToCapacity_TrimmingNeeded&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testTrimToCapacity_TrimmingNotNeeded&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;aside&gt;
I don’t endorse this pattern for naming tests in general, but this reflects common practice. In a real-life version of this example, I’d be writing &lt;em&gt;Learning Tests&lt;/em&gt; to help me understand how &lt;code&gt;ArrayList&lt;/code&gt; works in Java. In such a situation I often write tests oriented around each method and the various special cases, because I’m trying to document the API as designed. When designing new behavior in new modules or classes, I prefer not to name my tests for any particular method, function, or even class, so as not to couple—even in my own mind—the tests unnecessarily to an initial implementation.
&lt;/aside&gt;
&lt;p&gt;I can imagine finding this set of tests—and more—in a test called &lt;code&gt;ArrayListTest&lt;/code&gt;.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; You can already see two things:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;There are a lot of tests here.&lt;/li&gt;
&lt;li&gt;There is a fair amount of duplication here.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can also see that we can’t remove that duplication with just a single refactoring: the various tests fall into different groups, and so need us to organize them slightly differently.&lt;/p&gt;
&lt;h2 id=&quot;remove-duplication&quot;&gt;Remove Duplication&lt;/h2&gt;
&lt;p&gt;I don’t seem to have any problem understanding the names of these tests—I wrote them, so I guess that shouldn’t surprise me—which means that I will turn my attention to removing duplication.&lt;/p&gt;
&lt;figure style=&quot;width: 90%&quot;&gt;
&lt;a href=&quot;/permalink/putting-an-age-old-battle-to-rest&quot;&gt;&lt;img src=&quot;//blog.thecodewhisperer.com/images/age_old_battle/virtuous_cycle.png&quot; alt=&quot;Remove Duplication and Improve Names in small batches&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;
The Simple Design Dynamo&lt;sup&gt;TM&lt;/sup&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this case, duplication in the names of the tests will suggest different ways of reorganizing the tests than a simple refactoring of the duplicate code might suggest. Even though I haven’t written these tests out in code, I’ve seen them a number of times, so I can picture them very clearly. Especially when a programmer writes all these tests in one test case class, they typically end up with one line of setup code shared by all the tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Before
public void setUp() { theList = new ArrayList&amp;lt;String&amp;gt;(); }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Removing this duplication helps a little, but we can do much better. For example, looking at the tests for the “non-empty list” cases, I imagine I’ll find copied-and-pasted lists of “pre-populated” items.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Test
public void testSize_NonEmptyList() {
    theList.add(&amp;quot;jbrains is awesome&amp;quot;);
    theList.add(&amp;quot;jbrains is awesomer&amp;quot;);
    theList.add(&amp;quot;jbrains is even awesomer than that&amp;quot;);

    Assert.assertEquals(3, theList.size());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…and a little farther down…&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Test
public void testIsEmpty_NonEmptyList() {
    theList.add(&amp;quot;jbrains is awesome&amp;quot;);
    theList.add(&amp;quot;jbrains is awesomer&amp;quot;);
    theList.add(&amp;quot;jbrains is even awesomer than that&amp;quot;);

    Assert.assertFalse(theList.isEmpty());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I look at the “&lt;code&gt;isEmpty()&lt;/code&gt;, non-empty case” test, I get the idea that although I might want to check the “3” case for &lt;code&gt;size()&lt;/code&gt;, I might prefer to check the boundary case for &lt;code&gt;isEmpty()&lt;/code&gt;, meaning a list of one single item. Quite often, however, I see programmers merrily copy and paste lists of items to new tests because, well, we find that easier.&lt;/p&gt;
&lt;aside&gt;
Now that I say this, perhaps I should add a test for &lt;code&gt;testIsEmpty_BarelyNonEmptyList&lt;/code&gt; in order to distinguish the cases. I’ll add that to the to-do list I have by my computer.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;
&lt;/aside&gt;
&lt;h2 id=&quot;group-tests-by-fixture&quot;&gt;Group Tests by Fixture&lt;/h2&gt;
&lt;p&gt;Long ago, &lt;a href=&quot;#junit-recipes&quot;&gt;in a book far, far away&lt;/a&gt;, I wrote about grouping tests by fixture. I recommended that you “test behavior, not methods” (section 1.3.2) and “move special cases to their own fixture” (recipe 3.7). I gave some examples. It was fine. I encouraged the reader to remove duplication in the setup (now called &lt;code&gt;@Before&lt;/code&gt;) code. More than anything else, however, &lt;strong&gt;don’t let tests twiddle the fixture&lt;/strong&gt;. If a handful of tests want to share a fixture, then I prefer that they &lt;em&gt;all&lt;/em&gt; share the very same fixture, meaning the same objects in the same state. This becomes especially important when you start trying to reuse fixture objects using inheritance. (I used to do this; I tend not to do it any more. The cure always eventually hurts more than the disease.)&lt;/p&gt;
&lt;h2 id=&quot;junk-drawer&quot;&gt;Junk Drawer&lt;/h2&gt;
&lt;p&gt;You probably have a junk drawer in your house. You throw junk into it. Some of that junk you need, so you root around in it to find something specific, like a pen or a paperclip. Eventually, you find that you need a paperclip unusually often—usually to press a recessed &lt;strong&gt;reset&lt;/strong&gt; button on some electronic thing—and so you decide to put the paperclip somewhere to make it easier to find. If you put it in its own little compartment, then you’ll find it, but if you then start putting some other, not-so-related items in with the paperclip, then before long you find yourself with a second junk drawer.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; Then a third. Then you just have junk everywhere. It doesn’t work.&lt;/p&gt;
&lt;p&gt;So it goes when you try to organise fixture objects into a &lt;em&gt;setup&lt;/em&gt; function. This works great until the first time a test wants to change the fixture &lt;em&gt;just a little&lt;/em&gt; for its own purposes. For the first test, you don’t worry so much: you put it in the same test class, twiddle the fixture—what harm can one extra line of setup do?—then go along your merry way. The very next special case wants to twiddle the fixture in precisely the same way. Then a third. &lt;strong&gt;Now is the time to move these three tests into their own test class with their own fixture&lt;/strong&gt;, as I recommended in &lt;em&gt;JUnit Recipes&lt;/em&gt;. If you don’t do this now, then before you know it, there’s graffiti everywhere. Almost every test twiddles the fixture in some unexpected way. You find some of that fixture up in superclasses, and you become lost in a maze of &lt;code&gt;super()&lt;/code&gt; calls that you need to make at &lt;em&gt;just the right time&lt;/em&gt;, otherwise your tests vomit &lt;code&gt;NullPointerException&lt;/code&gt;s all over the place.&lt;/p&gt;
&lt;p&gt;Ewww. You should have moved those tests to their own fixture when you had the chance.&lt;/p&gt;
&lt;p&gt;When you find a group of tests inside a larger test class, you can either extract those tests by fixture or by action.&lt;a href=&quot;#fn5&quot; class=&quot;footnote-ref&quot; id=&quot;fnref5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt; I used to think that choosing between these options amounted to black magic, “skill”, or wisdom. Now I think I have a rule suitable for an &lt;em&gt;advanced beginner&lt;/em&gt; (on the &lt;a href=&quot;https://bit.ly/dreyfus-novice&quot;&gt;Dreyfus&lt;/a&gt; model) to use.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you name your tests using a convention like &lt;code&gt;test&amp;lt;action&amp;gt;_&amp;lt;special case&amp;gt;&lt;/code&gt;—for example, &lt;code&gt;testIsEmpty_NonEmptyList&lt;/code&gt;—then examine the test names for patterns. First look for multiple groupings of the same set of &lt;em&gt;special case&lt;/em&gt; words, then group those tests into a test class by fixture. Then look for multiple grounds of the same set of &lt;em&gt;action&lt;/em&gt; words, then group those tests into a test class by action.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think this works because the special case names generally correspond to similar fixtures. If you have a bunch of tests that need to operate on a “non-empty list”, then you’ll probably copy and paste the same three items into each list object in those tests. (I don’t claim to call this a &lt;em&gt;good thing&lt;/em&gt;, but we do it.) Moreover, if you try to organise the special case groupings by action instead, then you’ll move those tests away from each other into separate test classes, even though they have similar setup code. This creates a cohesion problem&lt;a href=&quot;#fn6&quot; class=&quot;footnote-ref&quot; id=&quot;fnref6&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt; solved by reorganising those tests by similar fixture.&lt;/p&gt;
&lt;h2 id=&quot;group-tests-first-by-special-cases-then-by-actions&quot;&gt;Group Tests First By Special Cases, Then By Actions&lt;/h2&gt;
&lt;p&gt;Returning to our tests for &lt;code&gt;ArrayList&lt;/code&gt;, we have&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testAdd_EmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testAdd_NonemptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testAdd_ListAtCapacity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testAdd_DuplicateItem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testContains_ItemFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testContains_ItemNotFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testContains_DuplicateItem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testSize_EmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testSize_NonEmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty_EmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty_NonEmptyList&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf_ItemFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf_ItemNotFound&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testTrimToCapacity_TrimmingNeeded&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testTrimToCapacity_TrimmingNotNeeded&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Following my proposed rule, I would end up first with these tests grouped by fixture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;EmptyListTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testAdd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testSize&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NonEmptyListTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testAdd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testSize&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BarelyNonEmptyListTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testIsEmpty&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MatchingItemsTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testContains&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NotMatchingItemsTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testContains&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DuplicateMatchingItemsTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testContains&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testIndexOf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also these tests grouped by function—the junk drawers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AddItemToListTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testListAtCapacity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testListNotYetAtCapacity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testItemAlreadyInList&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TrimArrayListToCapacityTest&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;testNeedsTrimming&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testDoesNotNeedTrimming&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, this doesn’t constitute an exhaustive test for &lt;code&gt;ArrayList&lt;/code&gt;, but you get the idea. You’ll notice that I’ve renamed some of the tests and added a few. By reorganizing the tests this way, a few ideas popped into my head, such as “adding an item when the list is not yet at capacity”. When I first wrote this list of tests, I thought of “not yet at capacity” as an unstated default assumption. Since Java creates an &lt;code&gt;ArrayList&lt;/code&gt; with a capacity of 10 items by default, I could think of &lt;code&gt;testAdd_EmptyList&lt;/code&gt; as implicitly checking the “not yet at capacity” case. This kind of implicit checking can lead to “holes in our tests”, which can lead to the dreaded “green bar, but there’s a bug” problem that brings us back to my old favorite: &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests are a scam&lt;/a&gt;. I don’t want to go there just now.&lt;/p&gt;
&lt;p&gt;Instead, let me close by proposing that you &lt;strong&gt;try grouping tests first by repeated special cases (which correspond to similar fixtures), then by actions&lt;/strong&gt;. I think you’ll like the results.&lt;/p&gt;
&lt;h2 id=&quot;if-i-group-tests-like-this&quot;&gt;&quot;If I Group Tests Like This…&lt;/h2&gt;
&lt;p&gt;…then I won’t be able to find anything!&quot; Srsly, this is 2014. Don’t you use &lt;code&gt;ag&lt;/code&gt; or &lt;code&gt;ack&lt;/code&gt; or &lt;code&gt;grep&lt;/code&gt; or something? Can’t you search your project for uses of the function &lt;code&gt;add()&lt;/code&gt;, or at worst, the regular expression &lt;code&gt;/\.add(/&lt;/code&gt;?!&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a name=&quot;junit-recipes&quot;&gt;&lt;a href=&quot;https://link.jbrains.ca/TEDGGm&quot;&gt;&lt;em&gt;JUnit Recipes: Practical Methods for Programmer Testing&lt;/em&gt;&lt;/a&gt;&lt;/a&gt;. I wrote ten years ago about the benefits of organizing tests by fixture, rather than by function. I never felt truly comfortable with how easily the reader could apply that advice. This article attempts to assuage my guilt at giving such questionable advice.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://bit.ly/QWK7do&quot;&gt;“Integrated Tests are a Scam”&lt;/a&gt;. The talk as I performed it at DevConFu in Jurmala, Latvia in December 2013. Don’t watch the Agile 2009 conference version any more.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/1npUxSf&quot;&gt;“Integrated Tests are a Scam”&lt;/a&gt;. The series of articles. Start with the oldest ones and work your way towards the present.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger and friends, &lt;a href=&quot;https://link.jbrains.ca/11hmmkp&quot;&gt;Understanding Coupling and Cohesion&lt;/a&gt;. 57 minutes of video. I invited some of my friends to discuss the nebulous concepts of coupling and cohesion in software design. How do we think about these topics? How do we understand the terms? How do we use that in our work as programmers? How do we teach it to others? How much does any of it even matter? Our invited guests: Corey Haines, Curtis Cooley, Dale Emery, J. B. Rainsberger, Jim Weirich, Kent Beck, Nat Pryce, Ron Jeffries.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/2cZejnV&quot;&gt;“Avoiding Distractions While Programming”&lt;/a&gt;. A quick introduction to keeping your head clear while programming.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Yes, I’m assuming Java here. Don’t let that fool you: I see exactly the same patterns in Ruby/PHP/Python as I do in Java/C#/C++/C.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;…we see little Father Down… Wait. Not a Benny Hill fan?&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Do you feel distracted while programming? I have some suggestions for you at &amp;lt;//blog.jbrains.ca/permalink/avoid-distractions-while-programming&amp;gt;.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;This phenomenon relates to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Broken_windows_theory&quot;&gt;Broken Windows Theory&lt;/a&gt; in which once we decide not to repair the first broken window in a neighborhood, vandalism and further damage follows soon thereafter.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn5&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Do you remember the “Three A’s” of &lt;em&gt;arrange&lt;/em&gt;, &lt;em&gt;act&lt;/em&gt;, and &lt;em&gt;assert&lt;/em&gt;? By &lt;em&gt;action&lt;/em&gt; I mean the function that you intend to test with that test.&lt;a href=&quot;#fnref5&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn6&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Although &lt;a href=&quot;https://link.jbrains.ca/11hmmkp&quot;&gt;we don’t generally agree&lt;/a&gt; on how to define cohesion, I find it useful to move similar things closer together and keep dissimilar things farther apart. This leads me towards higher (better) cohesion.&lt;a href=&quot;#fnref6&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sat, 04 Oct 2014 04:13:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/clean-up-those-nasty-junk-drawers</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/clean-up-those-nasty-junk-drawers</guid>
        
        
        <category>Improving Names</category>
        
      </item>
    
      <item>
        <title>Surviving Legacy Code with Golden Master and Sampling</title>
        <description>&lt;p&gt;You have inherited some code. Congratulations. Now you need to change it.&lt;/p&gt;
&lt;p&gt;There, there.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;#welc&quot;&gt;Michael Feathers once wrote&lt;/a&gt; that legacy code is “code without unit tests”. I use a slightly more general definition.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By “legacy code”, I mean &lt;strong&gt;profitable code that we feel afraid to change&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think that both parts matter. You probably accepted the “afraid to change” part without any need for convincing. (If not, then this article probably won’t interest you.) Moreover, if the code doesn’t generate significant value, then I don’t see much risk in changing it. If the cost of “getting it wrong” doesn’t significantly outweigh the profit we derive from “getting it right”, then who cares? Probably not I.&lt;/p&gt;
&lt;p&gt;I treat valuable code with considerable respect. It provides food for families. I treat difficult-to-change code also with considerable respect, although this comes more from fear than admiration. If we put these two things together, then, quite simply, one false move and I might destroy an order of magnitude more profit than the yearly cost to keep me around.&lt;/p&gt;
&lt;p&gt;This brings me to &lt;strong&gt;Rule Number Zero of Surviving Legacy Code&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Maximize safety.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We find ourselves in the typical chicken-and-egg problem: we want to write tests in order to refactor more safely, but then we remember that integrated tests are a scam℠&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; and decide that we’d rather break things apart a little in order to write less-costly-to-maintain tests. So which do we do first?&lt;/p&gt;
&lt;p&gt;In a situation like this, I like to go back to my guiding principles.&lt;/p&gt;
&lt;p&gt;Integrated tests are a scam℠ in part because they don’t put enough positive pressure on my designs and thereby don’t give me enough useful design feedback. Right now, &lt;em&gt;I don’t care about this&lt;/em&gt;. I already know that the design needs significant work. I also know that I can’t handle the torrent of feedback that microtests would give me about the design.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; &lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; If I want to use this principle to guide my behavior, then I need to find another justification.&lt;/p&gt;
&lt;p&gt;Integrated tests remain a scam℠ in part because of the combinatoric explosion in the number of tests I need to achieve a strong level of &lt;em&gt;coverage&lt;/em&gt;, which in this case correlates to &lt;em&gt;confidence&lt;/em&gt;. I might have to write millions of tests to achieve high coverage. I probably only have time to write hundreds of tests, in which case I have to gamble about the level of coverage. Perchance, could I not care about coverage in this situation?&lt;/p&gt;
&lt;p&gt;Test coverage—however one measures or defines it—links directly to safety in changing code.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; I want to use those tests as &lt;em&gt;change detectors&lt;/em&gt;. I want the red light that flashes the moment I make a mistake. Microtests, especially if I write them first, give me that. They help me find mistakes immediately. They help drive down the cost of making a mistake, an essential technique for managing risk.&lt;a href=&quot;#fn5&quot; class=&quot;footnote-ref&quot; id=&quot;fnref5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt; If I can’t write microtests cost-effectively, then what can I do?&lt;/p&gt;
&lt;p&gt;What if, instead of a red light that flashes the moment I make (almost) any mistake, I had a pink light that flashes when I make a really obvious mistake? I can’t have what I want, but I can afford this; will it do? It will help more than doing nothing. I will simply buy as much of this confidence as I can afford. To do this, I combine two simple ideas: &lt;strong&gt;Golden Master&lt;/strong&gt; and &lt;strong&gt;sampling&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;golden-master&quot;&gt;Golden Master&lt;/h2&gt;
&lt;p&gt;I use &lt;em&gt;Golden Master&lt;/em&gt; to help me detect changes in the behavior of a system when I can’t justify writing the typical kind of assertion that you’ve grown used to seeing in tests. I use this trick, for example, when I find it difficult to articulate the expected result of a test. Imagine a function whose output consists of an image. It happens quite often that a binary comparison between actual and expected result yields a &lt;em&gt;hyperactive&lt;/em&gt; assertion—one which frequently fails even when a human would judge that the test had passed. I suppose some people know tricks to make it easier to articulate “looks similar enough” for images, but I don’t know how to do that, and that leaves me to choose either a hyperactive bit-by-bit comparison or ongoing, manual inspection. Rather than revert to the Guru Checks Output antipattern&lt;a href=&quot;#fn6&quot; class=&quot;footnote-ref&quot; id=&quot;fnref6&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt;, however, I take a snapshot of the last-known acceptable output—I call that the &lt;em&gt;golden master&lt;/em&gt;—and save it for future use. When I run the test again, I compare the output to the golden master, and if they match, then the test passes; if they don’t match, then the test fails. This doesn’t make the code wrong, but it means that I need to check the result and decide whether the code needs fixing or the golden master needs replacing.&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;If your system already sends text to an output stream that you can capture, then you have the tools to use this technique.&quot;&gt;&lt;/span&gt; You can use Golden Master wherever you already have some output to check, even if you find the form of that output particularly challenging. With this technique, you simply diff the output and inspect the situation only when you find differences between the current test run and the golden master. If your system already sends text to an output stream that you can capture, then you have the tools to use this technique.
&lt;/p&gt;
&lt;h3 id=&quot;what-kind-of-output&quot;&gt;What Kind Of Output?&lt;/h3&gt;
&lt;p&gt;In short: anything that you can easily inspect. With luck, the system writes comprehensive text-based output to a predictable location, such as a local file system. With less luck, the system writes some kind of text-based output somewhere that you can collect. Most systems produce &lt;em&gt;logging output&lt;/em&gt;, which you can use as a kind of proxy for “the real thing”. You might prefer this, because it gives you the chance to trace intermediate results by adding more logging statements &lt;em&gt;relatively&lt;/em&gt; safely. (I have worked on systems where adding a logging statement changed some significant behavior, so I have to hedge my bets here.) If your system produces events for other systems, then you might add a listener that echoes the event as text (JSON?) to a simple file. If your system design doesn’t allow that flexibility, then you might add logging information just before and after sending the event. Let your imagination run wild. Whatever you need to do in order to capture results that you want to check, do it, but &lt;em&gt;do it carefully&lt;/em&gt;. Make the smallest changes you need in order to produce output that you can check, because that provides the tests you’ll use to make bigger changes with more confidence.&lt;/p&gt;
&lt;h3 id=&quot;what-about-noisy-output&quot;&gt;What About Noisy Output?&lt;/h3&gt;
&lt;p&gt;If your system produces “noisy” output, then you will probably want to filter the results. Noise can include insignificant things that change, such as timestamps and thread names; but it can also include insignificant things that don’t appear to change, such as user-friendly words. For example, in a game that reports “Joe has rolled a 6” when a player rolls the die, you might prefer to extract the parts that matter, transforming this into &lt;code&gt;roll: &quot;Joe&quot;, 6&lt;/code&gt;, so that your golden master doesn’t fall out of date when someone changes some irrelevant part of this text. All the same, don’t go overboard: don’t start building a parser for an arbitrary, unplanned, probably context-sensitive grammar. That way lies madness. (Of course, if a context-free grammar happens to describe the format, then go for it. You’ve always wanted to learn &lt;code&gt;lexx&lt;/code&gt; and &lt;code&gt;yacc&lt;/code&gt;, haven’t you?) Once you find yourself spending a significant amount of time filtering your golden master output—beyond what a few simple regular expressions can handle—consider that you might spend less time extracting a huge function and then writing &lt;code&gt;assertEquals()&lt;/code&gt; checks.&lt;/p&gt;
&lt;h2 id=&quot;sampling&quot;&gt;Sampling&lt;/h2&gt;
&lt;p&gt;I find one glaring problem with the Golden Master technique: if the output describes a long-running algorithm, process, or path through the system, then the golden master itself might describe only one of a thousand, million, or even billion potentially-interesting possible outputs. Welcome back to the combinatoric explosion problem that makes integrated tests such a scam℠. How do we proceed when we can’t possibly check the variety of paths through the system that we need to check?&lt;/p&gt;
&lt;p&gt;Ideally, we refactor! I know that if I can break my system into many smaller, composable pieces, then I turn products into sums: instead of checking combinations of paths through multiple parts of the system at once, I can check the handful of pairwise connexions between parts of the system in relative isolation. I could turn millions of tests into hundreds. Unfortunately, in our current situation, I don’t feel comfortable refactoring, so that means that I have to &lt;em&gt;sample&lt;/em&gt; the inputs and hope for the best.&lt;/p&gt;
&lt;p&gt;You can find more sophisticated sampling systems out there among blogs written by experienced testers, but they all amount to sampling: if I can’t try every combination of inputs, then I try some combinations of some of the inputs and aim for the best coverage that I can.&lt;/p&gt;
&lt;p&gt;This shouldn’t surprise you. You’ve done this before. You’ve written a function that operates on an integer, and you knew enough about the algorithm to identify boundary cases at, for example, -1, 0, and 1, as well as around 100 and 1000, so you check in and around the interesting boundary values and feel satisfied that the algorithm will work for the remaining few billion inputs. You were &lt;strong&gt;sampling&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In the case of legacy code, however, sometimes we can’t sample quite so intentionally. Sometimes &lt;em&gt;even when we limit our scope to characteristic inputs&lt;/em&gt;, we have so many combinations of those inputs that we still can’t afford to write and run all those tests. In some cases, we don’t even know how to identify the characteristic inputs. In other cases, the algorithm itself has a random element, defeating our goal of writing nice, deterministic, repeatable tests. Random sampling to the rescue.&lt;/p&gt;
&lt;p&gt;If you can use the random number generator to generate a stream of inputs to your system, then you can use this generate a collection of output files, and that collection can act as your golden master. You only need to control the random number generator by seeding it with the same stream of seeds every time. I use a simple linear generating function like &lt;code&gt;m + p * i&lt;/code&gt; where &lt;code&gt;m&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt; represent arbitrarily-chosen numbers and &lt;code&gt;i&lt;/code&gt; represents a loop index. Now I simply have to decide how big a sample to take. Generally speaking, a larger sample gives me more confidence in the sensitivity of the pink flashing light that signals possible danger.&lt;/p&gt;
&lt;p&gt;I adjust the size of the sample depending on how long it takes to execute a test run, and how much significantly that affects my flow while programming. I also adjust the size of the sample to match my fear level: the more worried I feel about getting something wrong, the larger sample I take while working, and I accept the cost of slowing down. I’d usually rather go a little too slow than a little too fast, because I know that the cost of making a mistake would likely dominate the savings from going more quickly.&lt;/p&gt;
&lt;h2 id=&quot;the-techniques-in-action&quot;&gt;The Techniques in Action&lt;/h2&gt;
&lt;p&gt;You can see an example of this technique in action by reading &lt;a href=&quot;//link.jbrains.ca/1AVawrV&quot;&gt;this code&lt;/a&gt;. If you’d like to see how I added this behavior to some legacy code, then &lt;a href=&quot;//link.jbrains.ca/1mmmKIW&quot;&gt;start at this commit&lt;/a&gt; and follow the process step by step.&lt;/p&gt;
&lt;p&gt;Although these techniques do not, on their own, guarantee success, when I combine Golden Master and Sampling, I can usually find a way to proceed safely. When I combine these with microcommitting&lt;a href=&quot;#fn7&quot; class=&quot;footnote-ref&quot; id=&quot;fnref7&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;7&lt;/sup&gt;&lt;/a&gt;, I can proceed at an even quicker pace. They help me avoid the Catch-22 problem that arises from needing to refactor dangerously unsafely in order to be able to refactor safely and sensibly. Where might you use Golden Master and Sampling to help get your arms (at least a little) around your legacy code?&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Michael Feathers, &lt;a name=&quot;welc&quot;&gt;&lt;a href=&quot;//link.jbrains.ca/jdXMTy&quot;&gt;&lt;em&gt;Working Effectively with Legacy Code&lt;/em&gt;&lt;/a&gt;&lt;/a&gt;. Still the classic work on winding your way through legacy code.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;//link.jbrains.ca/getting-started-with-gtd&quot;&gt;“Getting Started with Getting Things Done”&lt;/a&gt;. You don’t have time to read &lt;em&gt;Getting Things Done&lt;/em&gt;? Start here. Four pages. It’ll be fine.&lt;/p&gt;
&lt;p&gt;David Allen, &lt;a href=&quot;//link.jbrains.ca/WOXFIr&quot;&gt;&lt;em&gt;Getting Things Done&lt;/em&gt;&lt;/a&gt;. I use it. Not all of it, and not all the time, but I use its core principles quite significantly in managing my work and home lives. No cult, I promise.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;//link.jbrains.ca/1caX2Mq&quot;&gt;“A Proven Path to Effectiveness”&lt;/a&gt;. A “method” that combines Getting Things Done and Test-Driven Development aimed specifically at the beleaguered programmer.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;//link.jbrains.ca/1plDKK9&quot;&gt;texttest.org&lt;/a&gt;. A library to help you write text-based tests, such as I would use to provide golden masters. &lt;strong&gt;Do not download this tool until you have written your own golden master at least once. That is an order.&lt;/strong&gt; After that, use TextTest, because it really helps.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;You can find a series of articles on that topic by &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;clicking here&lt;/a&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;When diving into legacy code, I find it more important than ever to keep stuff out of my head. During the two hours it takes to safely refactor some large function, I’m probably going to spot 14 potentially-useful refactorings. I can’t chase every bunny, no matter how cute they are. I need to write those ideas down, get them out of my head, and get back to the tricky surgery at hand.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I see little point in spending energy generating a backlog knowing full well that I will never get around to doing about 80% of it. Who would volunteer to do &lt;em&gt;that&lt;/em&gt;? (Ask your project manager if &lt;a href=&quot;//www.jbrains.ca/training/value-driven-product-development&quot;&gt;value-driven product development&lt;/a&gt; is right for them.)&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I know that measuring test coverage can lead to some pretty terrible results, but for my purposes here, I assume an environment in which we don’t have that particular problem. We can act like adults, can’t we?&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn5&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I claim that “the agile approach” to risk management complements the typical approach to risk management of limiting the probability of failure in order to limit exposure. “The agile way”, if you will permit me to use this shorthand, involves limiting the cost of failure instead. Eventually I will replace this sentence with a link to an article that goes into this topic in more detail.&lt;a href=&quot;#fnref5&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn6&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Marcia, the &lt;em&gt;guru&lt;/em&gt;, looks at the output, pauses for a moment, then says, “Yep. That’s it.” If you want to re-run the test, then you need Marcia. That doesn’t seem to scale particularly well.&lt;a href=&quot;#fnref6&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn7&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Really frequent committing, like after changing a single line of code. No, really.&lt;a href=&quot;#fnref7&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 28 Sep 2014 09:09:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/surviving-legacy-code-with-golden-master-and-sampling</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/surviving-legacy-code-with-golden-master-and-sampling</guid>
        
        
        <category>Surviving Legacy Code</category>
        
      </item>
    
      <item>
        <title>&quot;I Like Mocks, But I Distrust Spies&quot;</title>
        <description>&lt;p&gt;Some time ago a client asked me some questions about spies and mocks. I wanted to share what we discussed with you.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So here’s the issue my mind has been toiling over…&lt;/p&gt;
&lt;p&gt;The project I’m on is using Jasmine for BDD. Technically though, I think most people aren’t actually executing real TDD/BDD. As in, they’re not letting the tests guide their design, but instead are sticking on unit tests at the end, after writing most of the code… this is what their tests suggest, at least.&lt;/p&gt;
&lt;p&gt;I see, in their tests, a lot of spies and mocks. This tends to worry me,… especially the spies.&lt;/p&gt;
&lt;p&gt;I see a lot of it as unnecessary, and even damaging. They appear to be reducing the module that they’re testing to nothing more than a series of spies and mocks. The thing they’re testing seems to bear little resemblance to the real run-time module.&lt;/p&gt;
&lt;p&gt;From my perspective, mocking is very good and even essential in the cases of module dependencies that:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Would add too many extraneous variables to the testing environment&lt;/li&gt;
&lt;li&gt;Add lag to the tests&lt;/li&gt;
&lt;li&gt;Are not semantically tied to the thing we’re testing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Examples I like are database mocks, ajax mocks etc.&lt;/p&gt;
&lt;p&gt;But spies…. I’m very unsure of the value of spies.&lt;/p&gt;
&lt;p&gt;The tests I’m reading are creating a series of spies… in fact, every method of the module is spied.. even private methods. The tests will call some public method (fir example &lt;code&gt;initiatePriceFeed()&lt;/code&gt;), and then assert success by ensuring that certain &lt;em&gt;spied&lt;/em&gt; methods have been called. This just seems to be testing the implementation… not the actual exposed behavior, which is what I thought BDD/TDD was all about.&lt;/p&gt;
&lt;p&gt;So finally, I have a few questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is the best way to decide whether a spy is necessary?&lt;/li&gt;
&lt;li&gt;Is it ever acceptable to test the implementation, instead of exposed behavior? (for example spying on private methods)&lt;/li&gt;
&lt;li&gt;How do you decide what to mock and what not to?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am sorry for the length of this email. There seem to be so many things I’d like to say and ask about TDD.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Note! In the Javascript world, it’s common to talk about “spies” rather than “stubs”. A spy and a stub do the same thing. They only differ in intent. In what follows, you can treat “spy” and “stub” as synonyms with, I think, no risk of confusion.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That sounds common. I started doing test-first programming, rather than test-driven development. I probably spent two years focusing on tests as tests before I felt comfortable letting my tests guide my design.&lt;/p&gt;
&lt;p&gt;I think the people writing all these spies and mocks do this because it “seems right”. People they respect do it. They need to spend some time practising the technique, so they do it at every opportunity. This corresponds to the Novice/Advanced Beginner stages of the &lt;a href=&quot;https://bit.ly/dreyfus-novice&quot;&gt;Dreyfus Model&lt;/a&gt;: either they just want to practise the technique (Novice), or they feel comfortable using spies/expectations&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, and treat every opportunity as an equally (Advanced Beginner) appropriate time to use them. Good news: this is a natural part of learning.&lt;/p&gt;
&lt;p&gt;Where to go next? Find one example where a module would benefit from depending on data, rather than another module. I go back to the difference between Virtual Clock (spy on the clock so that you can make it return hardcoded times) and Instantaneous Request (pass timestamps directly, rather than the clock, pushing the clock up one level in the call stack). Perhaps this will help people start to question where they could change their approach.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT!&lt;/strong&gt; Instantaneous Request isn’t necessarily always better than Virtual Clock. Which you choose is less important than the discussions and thoughts that lead you to the choice. Also: starting to use Instantaneous Request over Virtual Clock means that the programmer is evolving, not the code. What matters is not “use fewer spies”, but rather “don’t let spies become a Golden Hammer”. Spies still help, I use them frequently, and I wouldn’t give them up.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I wrote about this approach in some detail in &lt;a href=&quot;/permalink/beyond-mock-objects&quot;&gt;“Beyond Mock Objects”&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Regarding the value of spies, I don’t consider spies and expectations much different from one another. A spy is merely an expectation that doesn’t verify which methods were called—instead it waits for you to do that. In some tests, it’s not important to verify what happened, but rather to provide a hardcoded answer for any method our Subject uses. One rule of thumb: &lt;strong&gt;spies for queries, but expectations for actions&lt;/strong&gt;. This works because we tend to want more flexibility in our queries, but more precision in the actions we invoke. Think of the difference between &lt;code&gt;findAllOverdueBalances()&lt;/code&gt; and &lt;code&gt;findAllBalances().selectBy(&quot;overdue&quot;)&lt;/code&gt;—it doesn’t matter how I find all the overdue balances. Spies simply make it easier to hardcode 0, 1, a few, or a large number of overdue balances, as each test needs.&lt;/p&gt;
&lt;p&gt;So: spies for queries, but expectations for actions.&lt;/p&gt;
&lt;h2 id=&quot;spy-then-spy-then-spy&quot;&gt;Spy, then Spy, then Spy…&lt;/h2&gt;
&lt;p&gt;I understand your concern about series of spies, but let me check that I understand what you mean. When you say a &lt;em&gt;series&lt;/em&gt; of spies, do you mean spying on &lt;code&gt;A.getB()&lt;/code&gt; to return a spy &lt;code&gt;B&lt;/code&gt;, whose &lt;code&gt;B.getC()&lt;/code&gt; returns a spy &lt;code&gt;C&lt;/code&gt; so that you can spy on &lt;code&gt;C.theMethodIFindReallyInteresting()&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;As for ensuring that spied methods have been called, those “spies” become expectations, and it can feel like those tests only check the implementation. That’s OK. If the implementation is so simple that we can check it with a simple test, then that’s good! It’s like double-entry book-keeping in accounting. If the tests are complicated &lt;em&gt;and&lt;/em&gt; only check implementation, then that usually points to a missing abstraction, or at least, obsession with unnecessary details (could be a missing abstraction or could just be an unnecessarily complicated API). This last point is an example of not listening to what the tests are trying to tell you.&lt;/p&gt;
&lt;p&gt;Programmers generally have this feeling &lt;em&gt;eventually&lt;/em&gt; that expectations mean “I’m just checking the implementation”. I had the same feeling once, so I asked myself, “assuming that this actually makes sense, what am I missing?” Well, if the interactions between objects were simpler, then this “checking the implementation” issue wouldn’t cause any real problems, would it? In fact, it would only clarify what we’re trying to do. Maybe, then, when checking the implementation feels weird, we could ask about potential underlying design problems, and if those problems disappeared, then we’d feel less weird. This is one of those cases.&lt;/p&gt;
&lt;p&gt;Go to a few tests where you feel weird in this particular way, and look for duplication between the examples. You might be surprised!&lt;/p&gt;
&lt;h2 id=&quot;when-is-a-spy-necessary&quot;&gt;When Is A Spy “Necessary”?&lt;/h2&gt;
&lt;p&gt;You ask about “the best way” to decide whether a spy is necessary (maybe appropriate). I don’t know of One Best Way. I use them, then let duplication drive changes. I especially look for &lt;a href=&quot;/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;duplicating unnecessary details in the test&lt;/a&gt;. If I have to duplicate details in a handful of tests, just to be able to check some other part of the system, then perhaps I have two things in one place, and when I separate them, the corresponding spies become much simpler, and sometimes I can replace a spy with data (from Virtual Clock to Instantaneous Request).&lt;/p&gt;
&lt;h2 id=&quot;is-it-ever-acceptable&quot;&gt;Is It Ever Acceptable…?&lt;/h2&gt;
&lt;p&gt;You also ask whether it is ever acceptable to test the implementation instead of the behavior. “Is it ever acceptable…?” questions almost always have the answer “yes”, because we can always find a situation in which somewhat becomes acceptable. On the other hand, I don’t typically spy on private methods. If I need to know that level of detail in a test, then the test is trying to tell me that &lt;code&gt;A&lt;/code&gt; cares too much about the internals of &lt;code&gt;B&lt;/code&gt;. First, I try to remove unnecessary details from &lt;code&gt;A&lt;/code&gt;’s tests. Next, I look for duplication in &lt;code&gt;A&lt;/code&gt;’s tests. Especially if I spy on the same functions in the same sequence, that duplication points to a missing abstraction &lt;code&gt;C&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;so-when-to-mock&quot;&gt;So When to Mock?&lt;/h2&gt;
&lt;p&gt;I have two answers to this question. First, when do I use spies/expectations compared to simply using “the real thing”? I like to program to interfaces (or protocols, dependingon the language) and I like to clarify the contracts of those interfaces, something that expectations help me do effectively. To learn more about this, read the articles I list at the end related to contract tests. Especially read &lt;a href=&quot;/permalink/when-is-it-safe-to-introduce-test-doubles&quot;&gt;“When Is It Safe to Introduce Test Doubles?”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, when I’m not sure whether to use a spy or an expectation, I go back to the rule of thumb: &lt;strong&gt;spy on queries, but expect (mock) actions.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Wikipedia, &lt;a href=&quot;https://bit.ly/dreyfus-novice&quot;&gt;“Dreyfus model of skill acquisition”&lt;/a&gt;. Not everyone likes this model of how people develop skills. I find it useful and refer to it frequently in my work.&lt;/p&gt;
&lt;p&gt;c2.com, &lt;a href=&quot;https://c2.com/cgi/wiki?VirtualClock&quot;&gt;“Virtual Clock”&lt;/a&gt;. An overview of the Virtual Clock testing pattern, with further links.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/beyond-mock-objects&quot;&gt;“Beyond Mock Objects”&lt;/a&gt;. I use test doubles (mock objects) extensively in my designs and they help me clarify the contracts between components. Even so, using test doubles mindlessly can interfere with seeing further simplifications in our design.&lt;/p&gt;
&lt;p&gt;I apologise &lt;em&gt;again&lt;/em&gt; for not having collected my thoughts about collaboration and contract tests into a single work. I need to find the time and energy (simultaneously) to do that. In the meantime, I have a few articles on the topic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/permalink/contract-tests-an-example&quot;&gt;“Contract Tests: An Example”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/permalink/in-brief-contract-tests&quot;&gt;“In Brief: Contract Tests”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/permalink/who-tests-the-contract-tests&quot;&gt;“Who Tests the Contract Tests?”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/permalink/writing-contract-tests-in-java-differently&quot;&gt;“Writing Contract Tests Differently”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;In order to avoid confusion with the generic concepts of “mock objects” (better called “test doubles”), I use the term &lt;em&gt;expectations&lt;/em&gt; to refer to what many people consider a &lt;em&gt;mock&lt;/em&gt;: function &lt;code&gt;foo()&lt;/code&gt; should be called with arguments &lt;code&gt;1, 2, 3&lt;/code&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 15 Sep 2014 05:13:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/i-like-mocks</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/i-like-mocks</guid>
        
        
      </item>
    
      <item>
        <title>Let Code Flow Towards Better Design</title>
        <description>&lt;p&gt;I think that programmers worry far too much about design.&lt;/p&gt;
&lt;p&gt;No, I don’t mean that they should care less about design. I think that programmers worry so much about design that they forget to just program. As they try to learn more about how to design software well, they become more reluctant to write code, fearing that “it won’t be right”. I think that we contribute to this reclutance by writing articles with a tone that implies &lt;em&gt;don’t write code unless you write it my way&lt;/em&gt;. I don’t think we mean to do this, but we do it nonetheless.&lt;/p&gt;
&lt;p&gt;What if we thought about design a slightly different way? Let’s not think about design principles as constraints for how we write code, but rather as suggestions for &lt;em&gt;how code wants to flow&lt;/em&gt;. Focus your energy first on writing correct code, then use the principles of design that you’ve learned to guide the flow of code from where you’ve written it to where it seems to belong. If you prefer a more direct metaphor, then imagine you’re writing prose. Rather than obsessing over the rules of grammar on your first draft, use them to guide how you edit. Let yourself more freely write your first draft without fear of “getting it wrong”, then use your editing passes to fix grammar errors, improve clarity and elevate style.&lt;/p&gt;
&lt;p&gt;Now you’ve probably heard this before. “Make it work, then make it right, then make it fast.” This constitutes the same advice. So why repeat it? You probably also know that sometimes we need to hear the same advice in a variety of forms before we feel comfortable using it. I’ve been talking in my training classes about “code flow” for a few years, and it seems to help some people feel more comfortable adopting an evolutionary design approach. In particular it helps some programmers avoid feeling overwhelmed by design principles to the point of not wanting to write any code at all, for fear of “doing it wrong”. After all, the more we say that “code is a liability”, the more people will tend to think of writing code as an evil act. That sounds extreme, but so does some of our rhetoric!&lt;/p&gt;
&lt;p&gt;When I teach software design—usually through test-driven development—one or two people in the class commonly ask me questions like “Can I use set methods?” or “Can I write a second constructor?” which convey to me a feeling of reluctance to “break the rules”. I really don’t want my course participants to feel like I want to stop them from writing code; on the contrary, I want them to feel more comfortable writing code precisely because they can apply their newly-learned design pricniples to improve their designs easily and quickly over time. I expect them to feel &lt;em&gt;less&lt;/em&gt; fear as their design skills improve, because no matter what crap they write in the morning, they can mold it into something beautiful in the afternoon. I have to remind &lt;em&gt;myself&lt;/em&gt; to approach code this way, rather than worrying too much about “getting in right the first time”.&lt;/p&gt;
&lt;h2 id=&quot;an-example&quot;&gt;An Example&lt;/h2&gt;
&lt;p&gt;Consider &lt;a href=&quot;https://link.jbrains.ca/1ohWsSr&quot;&gt;this article on the topic of encapsulation&lt;/a&gt;. I like it. I think it explains a few key points about encapsulation quite well. Unfortunately, it includes a line that, out of its context, contributes to this fear-based mindset that I’ve seen so often:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you ever use a setter or define an attribute of a component from the outside, you’re breaking encapsulation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I remember myself as an inexperienced programmer trying to improve at my craft. That version of me would have read this sentence and thought &lt;em&gt;I must not use setters any more.&lt;/em&gt; This would invariably lead me to a situation where I would refuse to write a setter method, even when I have no other option. (Sometimes tools get in the way.) This way lies design paralysis. &lt;strong&gt;When I’ve written over the years about design principles, I’ve certainly not wanted to make it harder for you to write code.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-should-i-do-then&quot;&gt;What Should I Do, Then?&lt;/h2&gt;
&lt;p&gt;Later in the same article, the author writes this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s common in Rails projects to use patterns such as &lt;code&gt;User.where(&quot;something = something_else&quot;)&lt;/code&gt; from controllers or service classes. How do you know the internal of the database to be able to pass that SQL parameters? What happens if you ever change the database? Or &lt;code&gt;User&lt;/code&gt;? Instead, &lt;code&gt;User.some_method&lt;/code&gt; is the way to go.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I agree to the principle and the example. I would, however, like to highlight a different way to interpret this passage. &lt;strong&gt;Rather than&lt;/strong&gt; thinking, “I should never write &lt;code&gt;User.where(&quot;something = something_else&quot;)&lt;/code&gt;”, &lt;strong&gt;think of it this way instead&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I’ll write &lt;code&gt;User.where(&quot;something = something_else)&quot;&lt;/code&gt; for now, just because I know it should work, but I probably shouldn’t leave it like that once it’s working.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Don’t let design guidelines (like &lt;em&gt;improve encapsulation&lt;/em&gt;) stop you from writing the code you need to write in the moment (as a first draft), but rather use them to guide the next steps (your editing). Don’t let design guidelines stop you from getting things working, but rather use them to stop you from leaving freshly-written legacy code behind.&lt;/p&gt;
&lt;h2 id=&quot;so-whats-this-about-code-flow&quot;&gt;So What’s This About Code Flow?!&lt;/h2&gt;
&lt;p&gt;Many programmers offer suggestions (for varying meanings of “suggest”) for where to put code. Some programmers write frameworks to try to constrain where you put code, lest you make (what they consider) silly mistakes. This eventually leads even experienced programmers into situations where they feel like they’re stuck in some &lt;a href=&quot;https://link.jbrains.ca/1AEvAEQ&quot;&gt;Brazilesque bureaucracy&lt;/a&gt; preventing them from writing the one line of code they need to make something work. (You need a controller, a model, a DTO, a database client object, …) Instead of thinking of “the right place to put things”, I prefer to offer suggestions about how to move code closer to “where it belongs”.&lt;/p&gt;
&lt;p&gt;Going back to the previous example from that encapsulation article, I would certainly have no problem writing &lt;code&gt;User.where(&quot;role = &apos;admin&apos;&quot;)&lt;/code&gt; directly in a controller just to get things working, but I just know that if I leave the design at that, then I will have set a ticking time bomb for myself to explode a some unforeseen and, almost uncertainly, inopportune time. As a result, once I get my tests passing with this poorly-encapsulated code, then I can take a moment to look at that code, ask &lt;em&gt;what does this mean?&lt;/em&gt;, realize that it means “the user is an admin”, then extract the function &lt;code&gt;User.admin?&lt;/code&gt;. In the process, the &lt;strong&gt;details&lt;/strong&gt; in this code will have &lt;strong&gt;flowed&lt;/strong&gt; from the controller into the model, where they seem to belong.&lt;/p&gt;
&lt;p&gt;I have found this pattern repeating itself in all the major application frameworks I’ve ever used: while learning the framework I put code directly into the controller/transaction script/extension point, and after I’ve written several of these and found them difficult to test or change, the details flow into more suitable components, often representing a model or view (or a little bit of each). &lt;strong&gt;By understanding my design principles in terms of where code ought to flow, I get the benefits of better design without the paralysing fear that I might “get it wrong”.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So if you need to break encapsulation, just for now, just to get something working, then do it. Just don’t leave it like that.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Alexandre de Oliveira, &lt;a href=&quot;https://link.jbrains.ca/1ohWsSr&quot;&gt;“Complexity in Software 2: Honor Thy Encapsulation”&lt;/a&gt;. In this article, Alexandre talks about “real” and “perceived” complexity in software design, which seem to me to relate to Fred Brooks’ concepts of “essential” and “accidental” complexity. He also includes a definition for &lt;em&gt;encapsulation&lt;/em&gt; that I hadn’t read before, and that I quite like. Enjoy the article.&lt;/p&gt;
</description>
        <pubDate>Fri, 22 Aug 2014 13:18:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/let-code-flow-towards-encapsulation</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/let-code-flow-towards-encapsulation</guid>
        
        
      </item>
    
      <item>
        <title>Abstraction: The Goal of Modular Design</title>
        <description>&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
. &lt;a href=&quot;https://twitter.com/cyriux&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;cyriux&quot;&gt;@cyriux&lt;/span&gt;&lt;/a&gt; : Imho the best paper ever written in software engineering: &lt;a href=&quot;https://t.co/C6kmmj0ntl&quot;&gt;https://t.co/C6kmmj0ntl&lt;/a&gt; Parnas, 1972
&lt;/p&gt;
— Alistair Cockburn (&lt;span class=&quot;citation&quot; data-cites=&quot;TotherAlistair&quot;&gt;@TotherAlistair&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/TotherAlistair/statuses/495160023396671488&quot;&gt;August 1, 2014&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;I don’t intend to argue Alistair’s contention one way or the other, but I invite you to set aside some time to read David Parnas’ paper “On the Criteria To Be Used in Decomposing Systems into Modules”, which I have embedded in this article. Do not let yourself be put off by the quaint-sounding title. If you prefer, think of it as titled “The Essence of Modularity”.&lt;/p&gt;
&lt;p&gt;I care about this paper because I strive for modularity in designing software systems and I find that programmers routinely lose sight of both the what modularity offers them and what it means. I value modularity as a way to drive down the cost of changing software. I value that because most of what we do as programmers consists of changing software, and so it strikes me as a sensible place to economise.&lt;/p&gt;
&lt;p&gt;If you can’t take the time to read the whole paper now, then let me direct you to a particularly salient part of the conclusion.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We have tried to demonstrate by these examples that it is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enjoy the paper. In case the embedded viewer doesn’t work for you: &lt;a href=&quot;https://www.dia.uniroma3.it/~cabibbo/asw/altrui/parnas-1972.pdf&quot;&gt;click here&lt;/a&gt;.&lt;/p&gt;
&lt;embed style=&quot;margin: 2em 0 2em 0&quot; width=&quot;100%&quot; height=&quot;800&quot; src=&quot;https://www.dia.uniroma3.it/~cabibbo/asw/altrui/parnas-1972.pdf#view=Fit&quot;&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/modularity-details-pick-one&quot;&gt;“Modularity. Details. Pick One.”&lt;/a&gt;. We introduce modularity by refusing to let details burden us.&lt;/p&gt;
&lt;p&gt;Martin Fowler, &lt;a href=&quot;https://link.jbrains.ca/14NaGSY&quot;&gt;&lt;em&gt;Refactoring: Improving the Design of Existing Code&lt;/em&gt;&lt;/a&gt;. A classic text that takes an evolutionary approach to increasing modularity in a software system.&lt;/p&gt;
</description>
        <pubDate>Fri, 01 Aug 2014 13:16:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/abstraction-the-goal-of-modular-design</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/abstraction-the-goal-of-modular-design</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Refactoring CSS: Not Impossible</title>
        <description>&lt;p&gt;I wanted to change some of the styling at &lt;a href=&quot;https://www.jbrains.ca&quot;&gt;jbrains.ca&lt;/a&gt;, but I have a legacy Wordpress template, so I needed a way to start making incremental changes with something remotely approximating tests. I knew that I didn’t want to have to crawl every page to check that every pixel remained in the same place, in part because that would kill me, and in part because I don’t need every pixel to remain in the same place. I needed another way.&lt;/p&gt;
&lt;h2 id=&quot;how-to-refactor-cssscss&quot;&gt;How to Refactor CSS/SCSS&lt;/h2&gt;
&lt;p&gt;I chose to replace the raw CSS with SCSS using the &lt;a href=&quot;https://link.jbrains.ca/1kdj8pp&quot;&gt;WP-SCSS&lt;/a&gt; Wordpress plugin. Since I had all this legacy CSS lying around in imported files and I had fiddled with some of it before I knew how the original authors had organized it, I needed to consolidate the CSS rules as soon as possible so that I can change them without accidentally breaking them.&lt;/p&gt;
&lt;p&gt;First, I created one big CSS file (the “entry point”) that imports all the other CSS files. Then, in order to use WP-SCSS effectively, I needed to move the importants into a subdirectory &lt;code&gt;css/&lt;/code&gt;, so that I could generate CSS from only the SCSS located in &lt;code&gt;scss/&lt;/code&gt;. This meant changing some &lt;code&gt;@import&lt;/code&gt; statements that loaded images using a relative path. I fixed those with some simple manual checks that the images load correctly before and after the change. (Naturally, I discovered the problem by accident, then fixed it.) At this point I had one big CSS entry point that imported a bunch of other CSS files in from &lt;code&gt;css/&lt;/code&gt;. I committed this to version control and treated it as the Golden Master&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, I copied all the CSS “partials” into genuine SCSS partials and changed the entry point to import a single generated CSS file. I created an SCSS entry point that imports all the SCSS partials. This should generate the same CSS entry point, but get rid of all the little generated CSS “partials”. It did. I committed this to version control.&lt;/p&gt;
&lt;p&gt;Now I can freely change my SCSS, generate the CSS, and check the &lt;code&gt;git&lt;/code&gt; index for changes. As long as only the SCSS changes and the generated CSS doesn’t change, I definitely haven’t broken the CSS. If the generated CSS changes, then I check the affected web pages by hand and either undo the change or commit the generated CSS as the new golden master.&lt;/p&gt;
&lt;p&gt;I hope this helps you deal with your own legacy CSS. You know you have some.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;This refers to the Golden Master technique where we check the result once by hand, then compare future versions automatically to the hand-checked “golden master” to detect changes. It’s &lt;em&gt;like&lt;/em&gt; testing.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Fri, 30 May 2014 14:27:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/refactoring-css-not-impossible</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/refactoring-css-not-impossible</guid>
        
        
      </item>
    
      <item>
        <title>How TDD Affects My Designs</title>
        <description>&lt;p&gt;I &lt;a href=&quot;https://twitter.com/jbrains/status/205679396508549120&quot;&gt;have&lt;/a&gt; &lt;a href=&quot;https://twitter.com/jbrains/status/468555663929769984&quot;&gt;written&lt;/a&gt; &lt;a href=&quot;https://twitter.com/jbrains/status/314574600069607424&quot;&gt;elsewhere&lt;/a&gt; that people, not rules, do things. I have written this in exasperation over some people claiming that TDD has ruined their lives in all manner of ways. Enough!&lt;/p&gt;
&lt;p&gt;People, not rules, design software systems. People decide which rules to follow and when. The (human) system certainly influences them, but ultimately, the people decide. In particular, people, not TDD, decide how to design software systems. James Shore has recently written &lt;a href=&quot;https://link.jbrains.ca/1ktgs6B&quot;&gt;“How Does TDD Affect Design?”&lt;/a&gt; to offer his opinion, in which he leads with this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ve heard people say TDD automatically creates good designs. More recently, I’ve heard David Hansson say it creates design damage. Who’s right?&lt;/p&gt;
&lt;p&gt;Neither. TDD doesn’t create design. You do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I agree. Keith Braithwaite responded in a comment with this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TDD does not by itself create good or bad designs, but I have evidence (see &lt;a href=&quot;https://link.jbrains.ca/1ktgHPg&quot;&gt;“Complexity and Test-First 0”&lt;/a&gt;) suggesting that it does create different designs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keith’s comment triggered me to think about how practising TDD has affected the way I design software systems, of which this article represents a summary. I might add more to this list over time. If you’ve noticed an interesting pattern in your designs that you attribute to your practice of TDD, then please share that in the comments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More value objects, meaning objects with value-equality over identity-equality&lt;/strong&gt;. I do this more because I want to use &lt;code&gt;assertEquals()&lt;/code&gt; a lot in my tests. This also leads to smaller functions that return a value object. This also leads specifically to more functions that return a value object signifying the result of the function, where I might not have cared about the result before. Sometimes this leads to unnecessary code, and when it does, I usually find that I improve the design by introducing a missing abstraction, such as an event.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More fire-and-forget events&lt;/strong&gt;. I do this more because I want to &lt;a href=&quot;/permalink/what-your-tests-dont-need-to-know-will-hurt-you&quot;&gt;keep irrelevant details out of my tests&lt;/a&gt;. Suppose that function X should cause side-effect Y. If I check for side-effect Y, then I have to know the details of how to product side-effect Y, which usually leads to excessive, duplicate setup code in both X’s tests and Y’s tests. Not only that, but when X’s tests fail, I have to investigate to learn whether I have a problem in X or Y or both. Whether I approach this mechanically (remove duplication in the tests) or intuitively (remove irrelevant details from the tests), I end up introducing event Z and recasting my expectations of X to “X should fire event Z”. This kind of thing gives many programmers the impression of “testing the implementation”, whereas I interpret this as “defining the essential interaction between X and the rest of the system”. The decision to make function X fire event Z respects the Open/Closed Principle: inevitably I want X to cause new side-effects A, B, and C. By designing function X as a source for event Z, I can add side-effects A, B, and C as listeners for event Z without changing anything about function X. This leads me to see the recent (as of 2014) trend towards Event Sourcing as a TDD-friendly trend.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More interfaces in languages that have interface types&lt;/strong&gt;. In the old days, we had to introduce interfaces (in Java/C#) in order to use the cool, new dynamic/proxy-based mocking libraries, like EasyMock and JMock. Since the advent of bytecode generators like &lt;code&gt;cglib&lt;/code&gt;, we no longer need to do this, but my habit persists of introducing interfaces liberally. Many programmers complain about having only one implementation per interface, although I still haven’t understood what makes that a problem. If the language forces me to declare an interface type in order to derive the full benefits of abstraction, then I do it. At least it encourages me to organize and document essential interactions between modules in a way that looser languages like Ruby/Python/PHP don’t. (Yes, we &lt;em&gt;can&lt;/em&gt; implement interfaces in the duck-typing languages, but Java and C# force us to make them a separate type if we want to use them.) Moreover, the test doubles themselves act as additional implementations of the interfaces, which most detractors fail to notice. They might argue that I overuse interfaces, but I argue that they underuse them. Interfaces provide an essential service: &lt;strong&gt;they constrain and clarify the client’s interaction with the rest of the system&lt;/strong&gt;. &lt;a href=&quot;https://bit.ly/QWK7do&quot;&gt;Most software flaws that I encounter amount to muddled interactions—usually misunderstood contracts—between modules&lt;/a&gt;. I like the way that the interfaces remind me to define and &lt;em&gt;refine&lt;/em&gt; the contracts between modules.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Immutability&lt;/strong&gt;. As functional programming languages have become more popular, I’ve noticed more talk about mutability of state, with an obvious leaning towards immutability. In particular, not only do I find myself wanting functions more often to return value objects, but specifically &lt;em&gt;immutable&lt;/em&gt; value objects. Moreover, thinking about tests encourages me to consider the pathological consequences of mutability. This happened recently when I wrote &lt;a href=&quot;/permalink/the-curious-case-of-tautological-tdd&quot;&gt;“The Curious Case of Tautological TDD”&lt;/a&gt;. Someone responded to the code I’d written pointing out a problem in the case of a mutable &lt;code&gt;Cars&lt;/code&gt; class. I had so long ago decided to treat all value objects as immutable that I’d even forgot that the language doesn’t naturally enforce that immutability. I’ve valued immutability for so long that, for me, it goes without saying. I reached this point after writing too many tests that only failed when devious programmers take advantage of unintended mutability, such as when a function returns a Java &lt;code&gt;Collection&lt;/code&gt; object. I went through a phase of ensuring that I always returned an unmodifiable view of any &lt;code&gt;Collection&lt;/code&gt;, but after a while, I simply decided to treat every return value as immutable, for the sake of my sanity. Functional languages push the programmer towards more enforced immutability, and even the eradication of state altogether. I feel like my experience practising TDD in languages like Java and Ruby have prepared me for this shift, so it already feels quite natural to me; on the contrary, it annoys me when I have to work in a language that doesn’t enforce immutability for me.&lt;/p&gt;
&lt;p&gt;How has TDD affected the way you design? or, perhaps more importantly, what about the way TDD might affect your designs makes you uneasy about trying it? I might have some useful advice for you.&lt;/p&gt;
</description>
        <pubDate>Thu, 22 May 2014 14:34:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/how-tdd-affects-my-designs</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/how-tdd-affects-my-designs</guid>
        
        
      </item>
    
      <item>
        <title>The Curious Case of Tautological TDD</title>
        <description>&lt;p&gt;In 2014 I read an article with the provocative title &lt;a href=&quot;#ref-mockists-are-dead&quot;&gt;“Mockists are Dead. Long live Classicists.”&lt;/a&gt;. In it, the author frames mock objects (I assume that they mean all &lt;em&gt;test doubles&lt;/em&gt;, as opposed to specifically method/function expectations) as “dangerous” and warns against a mistake he calls “tautological TDD”, which he describes as writing tests that merely repeat an idea in different words. This sounds risky to me, and something I’d probably want to warn against, but not something that I tend to do, so I wondered how they had seen test doubles used that would create this problem. I examined his example.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;interlude-examples-of-tautologies-in-tests&quot;&gt;Interlude: Examples of Tautologies in Tests&lt;/h2&gt;
&lt;p&gt;I don’t mean to claim that nobody makes this mistake. &lt;em&gt;I&lt;/em&gt; have made mistakes like this in the past. Every person who uses test doubles &lt;em&gt;eventually&lt;/em&gt; writes a test that looks like this:&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# ...several lines of code setting up test doubles...
foo = double(&amp;quot;a most excellent Foo&amp;quot;)
foo.stub(:bar).with(1, 2, 3).and_return(&amp;quot;hello!&amp;quot;)
# ...several more lines of code setting up other test doubles...
# ...several more lines of code pushing some method down the desired logic path...
# ...too many assertions, because we&amp;#39;re not sure what to check...
assert_equals &amp;quot;hello!&amp;quot;, foo.bar(1, 2, 3)
# ...several more assertions, because programming is hard!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I strip away all the irrelevant lines of code, then it becomes much easier to spot the obvious, silly mistake. This test merely stubs a function, then verifies the stub. Congratulations! Now that you have checked the test-double library, maybe you can check your own code! (I kid because I love. If you haven’t written this test at least once, then you haven’t been pushing yourself out of our comfort zone enough.)&lt;/p&gt;
&lt;p&gt;A simpler example boils down to this:&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;assert_equals 7 + 4, Fraction(7).plus(Fraction(4))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the tautology consists of using the algorithm to check itself, since &lt;code&gt;plus()&lt;/code&gt; probably uses integer arithmetic to handle the backwards-compatible case of adding fractions that are also integers. If you perform the Saff Squeeze&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; on this case, then you’ll eventually get down to&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;assert_equals 7 + 4, 7 + 4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and although you can simply look at this code and see that it’s right, I can envision a more complicated algorithm which I’d find easy to get wrong the same way in both places, resulting in a test that provides a false sense of security.&lt;/p&gt;
&lt;h2 id=&quot;back-to-our-main-story&quot;&gt;Back To Our Main Story…&lt;/h2&gt;
&lt;p&gt;The example centers around a &lt;code&gt;CarRepository&lt;/code&gt;, which appears to implement the &lt;a href=&quot;#references&quot;&gt;Domain-Driven Design&lt;/a&gt; Repository pattern in a straightforward way. The production code looks like this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;public class CarRepository {
  private ServiceHeaderFactory serviceHeaderFactory;
  private CarService carService;

  public CarRepository(ServiceHeaderFactory serviceHeaderFactory,
                       CarService carService) {
    this.serviceHeaderFactory = serviceHeaderFactory;
    this.carService = carService;
  }
  
  public Cars findAll() {
    ServiceHeader serviceHeader = serviceHeaderFactory.create();
    return carService.findAll(serviceHeader);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The test looks like this:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void shouldRetrieveCarsFromCarServiceUsingTheRightServiceHeader() throws Exception {
  // GIVEN
  ServiceHeader serviceHeader = new ServiceHeader();
  ServiceHeaderFactory serviceHeaderFactoryMock = mock(ServiceHeaderFactory.class);
  when(serviceHeaderFactoryMock.create()).thenReturn(serviceHeader);
  CarService carServiceMock = mock(CarService.class);
  CarRepository carRepository = new CarRepository(serviceHeaderFactoryMock, carServiceMock);

  // WHEN
  carRepository.findAll();

  // THEN
  verify(carServiceMock).findAll(serviceHeader);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The author calls this test “tautological” because the checks appear only to duplicate the implementation. I agree: the &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;then&lt;/strong&gt; lines…&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;when(serviceHeaderFactoryMock.create()).thenReturn(serviceHeader)
verify(carServiceMock).findAll(serviceHeader)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…correspond perfectly to a couple of lines in the production code.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;ServiceHeader serviceHeader = serviceHeaderFactory.create()
return carService.findAll(serviceHeader)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this, the author reasons that the test provides no useful information, categorizes it as redundant, labels it “tautological”, and considers it dangerous. He writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When we write tests this way, most of the time if the implementation changes, we end up changing the expectations of the test as well and yeah, the tests pass automagically. But without knowing much about its &lt;strong&gt;behaviour&lt;/strong&gt;. These tests are a mirror of the implementation, therefore tautological.—Fabio Pereira&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;another-interpretation&quot;&gt;Another Interpretation&lt;/h2&gt;
&lt;p&gt;I understand the author’s perspective, and I remember feeling skeptical about this myself. It felt strange seeing this duplication, and it seemed like the same thing every time: the expectation at the end of my test corresponded to the last line of my production method, and the stubs corresponded to almost every other line of the method. I thought that this must fly in the face of &lt;em&gt;Don’t Repeat Yourself&lt;/em&gt;, &lt;em&gt;Once and Only Once&lt;/em&gt;, and &lt;em&gt;The Four Elements of Simple Design&lt;/em&gt;, and that made me nervous.&lt;/p&gt;
&lt;p&gt;Let me offer another way to interpret the situation. Some objects interact very, very simply with their collaborators. Some objects act as simple mediators, such as those implementing the Template Method pattern. It seems pretty reasonable to me that the checks for a mediator of only two collaborators with a single code path would look too simple. I don’t think of this as a consequence of using mock objects, but rather a consequence of a very simple design. &lt;strong&gt;I consider this a good thing&lt;/strong&gt;. Next month, when we discover that this mediator needs to do more, I suspect that I’ll find it easy to understand and easy to add new behavior.&lt;/p&gt;
&lt;h2 id=&quot;what-do-we-really-have-here&quot;&gt;What Do We Really Have Here?&lt;/h2&gt;
&lt;p&gt;The author’s example leaves me a bit confused. I don’t quite understand the division of responsibility among the &lt;code&gt;CarRepository&lt;/code&gt;, the &lt;code&gt;ServiceHeaderFactory&lt;/code&gt; and the &lt;code&gt;CarService&lt;/code&gt;. Since I can’t use the author a definitive source of information, let me draw some conclusions from the code itself. It seems that &lt;code&gt;CarService&lt;/code&gt; bears the responsibility for finding cars based on something called the &lt;em&gt;service header&lt;/em&gt;. It seems that &lt;code&gt;CarRepository&lt;/code&gt; wants to “find all the cars”, but doesn’t want to specify a service header, pushing that responsibility up to the caller. And at this point, I have no idea why &lt;code&gt;CarRepository&lt;/code&gt; even exists.&lt;/p&gt;
&lt;p&gt;Meet Bob.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/the-curious-case-of-tautological-tdd/quizzical-bob.png&quot; alt=&quot;Bob.&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Bob.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Bob has a &lt;em&gt;service header&lt;/em&gt; (whatever that is) and wants to find all the corresponding cars, but he can’t figure out how to make that happen.&lt;/p&gt;
&lt;p&gt;Looking at the code available, Bob has two options:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;new CarService(...).findAll(bobsServiceHeader)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;new CarRepository(new ServiceHeaderFactory() {
  public ServiceHeader create() {
    return bobsServiceHeader;
  }
}).findAll();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I see a bewildered and bemused look on Bob’s face. I think I understand why. I have no idea what value &lt;code&gt;CarRepository&lt;/code&gt; brings to the design. So far, it turns a method parameter into an injectable constructor parameter. So far, it serves only to obscure the notion that one looks for cars relative (somehow) to a service header.&lt;/p&gt;
&lt;p&gt;Put yourself in Bob’s shoes. You have a service header. You want the corresponding cars. (I don’t even need to know what “correspond” means yet in this context, and so far, I don’t need to.) You look for a library function to do this for you. What do you expect?&lt;/p&gt;
&lt;p&gt;I know that I expect a function that maps a service header onto a set of cars. Something like&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;Collection&amp;lt;Car&amp;gt; findAllCarsBy(serviceHeader)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You know what I &lt;strong&gt;don’t&lt;/strong&gt; expect?! Something like&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Please put your service header in an envelope and write “Service Header Factory” on the outside of it (ignore the words on the envelope—Jake knows what they mean), then give that envelope to Jake over there. Jake’s a good boy. Ask Jake for all the cars, at which point Jake will open the envelope, read the service header, and tell you all the cars that correspond. OK? Good boy, that Jake.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We’d better have a damn good reason for making Bob jump through all these hoops to find the cars that correspond to his service header.&lt;/p&gt;
&lt;p&gt;If Bob could only use &lt;code&gt;CarService&lt;/code&gt; directly, then he wouldn’t have to deal with Jake at all. We could make this whole problem disappear by letting Bob use &lt;code&gt;CarService&lt;/code&gt; directly. In this case, Bob would have the chance to write typical, straightforward collaboration tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;stub &lt;code&gt;CarService&lt;/code&gt; to return convenient collections of &lt;code&gt;Car&lt;/code&gt;s for his purposes, following the pattern of 0, 1, many, lots, oops.&lt;/li&gt;
&lt;li&gt;set an expectation on &lt;code&gt;CarService&lt;/code&gt; to verify that his code asks for cars corresponding to the correct service header.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;He might not need both of these kinds of tests, but he has the option, and I would certainly not label any of those tests “tautological”.&lt;/p&gt;
&lt;p&gt;Of course, if I simply defined the problem away, you’d want your money back, so I need to transport myself into a universe in which we have damn good reasons for making Bob jump through all these hoops to find the cars that correspond to his service header.&lt;/p&gt;
&lt;h2 id=&quot;some-damn-good-reasons&quot;&gt;Some Damn Good Reasons…&lt;/h2&gt;
&lt;p&gt;Why might we need to expose the “find all cars for a service header” feature through &lt;code&gt;CarRepository&lt;/code&gt; rather than &lt;code&gt;CarService&lt;/code&gt;?&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;We need to adapt this feature to a frozen interface (like a framework) that disallows specifying the &lt;em&gt;service header&lt;/em&gt; as a function parameter.&lt;/li&gt;
&lt;li&gt;We want to shield clients from the difficulty of instantiating &lt;code&gt;CarService&lt;/code&gt;.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;We want, for the purposes of this particular application, to interpret “all cars” to mean “all cars corresponding to a specific service header”.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since these all seem plausible, let me address them in turn.&lt;/p&gt;
&lt;h3 id=&quot;carrepository-as-adapter&quot;&gt;&lt;code&gt;CarRepository&lt;/code&gt; As Adapter&lt;/h3&gt;
&lt;p&gt;Thinking back to &lt;a href=&quot;#references&quot;&gt;Design Patterns&lt;/a&gt;, we use the term &lt;em&gt;Adapter&lt;/em&gt; to refer to an object with the responsibility of exporting another object (the delegate) using a more convenient interface. So maybe Fabio needs &lt;code&gt;CarRepository&lt;/code&gt; to act as an Adapter for &lt;code&gt;CarService&lt;/code&gt;. OK. Let’s assume that. What now?&lt;/p&gt;
&lt;p&gt;I have &lt;code&gt;CarService.findAll(serviceHeader)&lt;/code&gt;, but my clients demand the interface &lt;code&gt;CarRepository.findAll()&lt;/code&gt;. I have two choices: choose a default value for &lt;code&gt;serviceHeader&lt;/code&gt; or make it a constructor parameter. I’ll explore the first of these options below, because it equates to interpreting “all cars” to mean “all cars corresponding to a specific service header”. Here, I’ll assume that clients need to retain the option to pass the &lt;code&gt;serviceHeader&lt;/code&gt; into the &lt;code&gt;CarRepository&lt;/code&gt; for &lt;code&gt;findAll()&lt;/code&gt; to use.&lt;/p&gt;
&lt;p&gt;Let me repeat that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Clients need to retain the option to pass the &lt;code&gt;serviceHeader&lt;/code&gt; into the &lt;code&gt;CarRepository&lt;/code&gt; for &lt;code&gt;findAll()&lt;/code&gt; to use.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Guess what, folks: that describes exactly what this class needs to do. It describes &lt;strong&gt;the essential interactions&lt;/strong&gt; between &lt;code&gt;CarRepository&lt;/code&gt; and its collaborator &lt;code&gt;CarService&lt;/code&gt;. &lt;code&gt;CarRepository&lt;/code&gt; has the responsibility of giving the correct &lt;code&gt;serviceHeader&lt;/code&gt; (and we haven’t decided how it will get that yet) to &lt;code&gt;CarService.findAll()&lt;/code&gt;. Now, when we articulate it like that, it sounds like we’re assuming the implementation, which takes us back to the “tautological” objection that brought us all here right now.&lt;/p&gt;
&lt;p&gt;I see it differently.&lt;/p&gt;
&lt;p&gt;I have a &lt;code&gt;CarService&lt;/code&gt; with a clear interface for mapping a service header to a collection of cars. I have an annoying client who insists on asking me for “all the cars” without specifying that service header. Unfortunately, I don’t know how to do that, so as a compromise, I tell the client that &lt;strong&gt;as long as it gives me the service header another way, then I’ll have the information I need to find “all the cars”.&lt;/strong&gt; (Yeah… it sounds stupid to me, too, so I hope this isn’t how the real system in Fabio’s example works. If it is, then I empathize with his situation.) Either way, &lt;strong&gt;my job entails connecting the service header to the &lt;code&gt;CarService&lt;/code&gt;, because my client curiously insists on doing this the hard way&lt;/strong&gt;. We’ve all been there. &lt;strong&gt;It forms part of the contract between the Service and its collaborators.&lt;/strong&gt; A contract is just a choice, after all—it doesn’t need to “make sense”.&lt;/p&gt;
&lt;p&gt;If my client would just give me the damn service header along with the request to “find all the cars”—you know, a function parameter—then we wouldn’t need any of this extra complication. Unfortunately, my client insists on doing things &lt;em&gt;their&lt;/em&gt; way. Fine. They can have a &lt;code&gt;CarRepository&lt;/code&gt;, but &lt;strong&gt;they have to provide the service header through the repository’s constructor, and the repository will make sure that it uses that service header (and not some other one) to “find all the cars”.&lt;/strong&gt; Will that make you happy, client?!!?&lt;/p&gt;
&lt;div class=&quot;aside&quot; data-markdown=&quot;1&quot;&gt;
&lt;p&gt;In terms of Java 8 standard libraries, the Service needs a Provider/Supplier of Service Headers, and so I would use the explicit type &lt;code&gt;Supplier&amp;lt;ServiceHeader&amp;gt;&lt;/code&gt;. In the old days of Java, I would need my own custom interface for this, and I would probably have called it &lt;code&gt;ServiceHeaderFactory&lt;/code&gt; or &lt;code&gt;ServiceHeaderProvider&lt;/code&gt;. I would use a &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;structural name&lt;/a&gt; because the entire notion seems very artificial and might have no natural meaning in the domain. It makes sense, after all!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Based on this, the test becomes clear to me. In words: the repository had better pass to &lt;code&gt;CarService.findAll()&lt;/code&gt; whichever &lt;code&gt;serviceHeader&lt;/code&gt; it received from its client (through the Supplier/Factory), and not a different one; it had better return the resulting &lt;code&gt;Car&lt;/code&gt;s unfiltered back to the client.&lt;/p&gt;
&lt;p&gt;I see two tests, although if you wanted to write them as a single test, I would argue with you for 15 seconds before going along with your decision.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Stub &lt;code&gt;CarService.findAll(anything())&lt;/code&gt; to return &lt;code&gt;arbitrarySetOfCars&lt;/code&gt;. Now &lt;code&gt;CarRepository.findAll()&lt;/code&gt; should be &lt;code&gt;arbitrarySetOfCars&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When I call &lt;code&gt;new CarRepository(carService, myServiceHeader).findAll()&lt;/code&gt;, someone should call &lt;code&gt;carService.findAll(myServiceHeader)&lt;/code&gt;, matching the parameter exactly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To avoid a deep philosophical argument (at least for now), I’ve combined these into a single test:&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void searchesForCarsWithTheRightServiceHeader() throws Exception {
  final Cars cars = new Cars(new Car(&amp;quot;irrelevant car name&amp;quot;));
  final ServiceHeader serviceHeader = new ServiceHeader();

  final CarService carService = mock(CarService.class);

  // Implicitly verifies that findAll() receives the correct argument
  when(carService.findAll(serviceHeader)).thenReturn(cars);

  final CarRepository carRepository = new CarRepository(carService, serviceHeader);

  assertSame(cars, carRepository.findAll());
}&lt;/code&gt;&lt;/pre&gt;
&lt;aside&gt;
Just to simplify the discussion, I’ve assumed the best-case scenario of an immutable &lt;code&gt;Cars&lt;/code&gt; object. I would hate to jump through the additional hoops necessary if someone had made &lt;code&gt;Cars&lt;/code&gt; mutable. (Don’t do that. Really.)
&lt;/aside&gt;
&lt;p&gt;Far from “tautological”, this test describes &lt;strong&gt;the very purpose&lt;/strong&gt; of &lt;code&gt;CarRepository&lt;/code&gt;: it relies on &lt;code&gt;CarService&lt;/code&gt; to find the right cars, but it has to provide the right &lt;code&gt;serviceHeader&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uh… why not just write integrated tests?&lt;/strong&gt; Fabio recommended this in his article. I don’t feel the need to duplicate all the tests for &lt;code&gt;CarService&lt;/code&gt; in order to test &lt;code&gt;CarRepository&lt;/code&gt;. I also don’t feel comfortable testing &lt;code&gt;CarService&lt;/code&gt; only through &lt;code&gt;CarRepository&lt;/code&gt;, especially given that &lt;code&gt;CarService&lt;/code&gt; exports a much more convenient interface to its clients. If anything, I wouldn’t bother testing &lt;code&gt;CarRepository&lt;/code&gt; and put all my energy into testing &lt;code&gt;CarService&lt;/code&gt;. Seriously.&lt;/p&gt;
&lt;h3 id=&quot;hiding-the-ugliness-of-instantiating-carservice&quot;&gt;Hiding The Ugliness of Instantiating &lt;code&gt;CarService&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Now imagine that whoever wrote &lt;code&gt;CarService&lt;/code&gt; made this class catastrophically difficult to instantiate. Nothing changes. In fact, all the more reason &lt;em&gt;not&lt;/em&gt; to write tests that integrate &lt;code&gt;CarRepository&lt;/code&gt; to &lt;code&gt;CarService&lt;/code&gt;: the code to set up &lt;code&gt;CarService&lt;/code&gt; would make us throw up in our mouths a little. This pushes me even more strongly to insist on using test doubles for &lt;code&gt;CarService&lt;/code&gt; in order to bypass its painful constructor. I’d still write the same tests that I’ve described just a few paragraphs ago, and for the same reasons.&lt;/p&gt;
&lt;p&gt;However, and much to my surprise, if we have a &lt;code&gt;CarService&lt;/code&gt; that takes so much effort to instantiate, then we probably also have a &lt;code&gt;CarService&lt;/code&gt; that takes too much effort to test. This nudges me in the direction of integrated tests for &lt;code&gt;CarRepository&lt;/code&gt; &lt;strong&gt;only because we probably have no tests for &lt;code&gt;CarService&lt;/code&gt; itself&lt;/strong&gt;. In this case, we’d have no duplication. You could probably talk me into this, even without a bribe. I’d eventually want to do one of two things: either collapse &lt;code&gt;CarService&lt;/code&gt; into &lt;code&gt;CarRepository&lt;/code&gt; or redesign &lt;code&gt;CarService&lt;/code&gt;’s constructor to suck less. In the first case, the integrated tests would no longer integrate things. In the second case, the integrated tests would (mostly) transform into &lt;code&gt;CarService&lt;/code&gt; tests and I’d want to write the same &lt;code&gt;CarRepository&lt;/code&gt; tests as I described just a few paragraphs ago, and for the same reasons.&lt;/p&gt;
&lt;h3 id=&quot;choosing-a-service-header&quot;&gt;Choosing a Service Header&lt;/h3&gt;
&lt;p&gt;If we don’t need to adapt the sensible, simple, delightful &lt;code&gt;CarService&lt;/code&gt; interface to connect to an insane, unreasonable, evil client that insists on &lt;code&gt;findAll()&lt;/code&gt; with no parameters, then I can only think of one reason for &lt;code&gt;CarRepository&lt;/code&gt; to exist: to decide on a service header. Maybe for this particular application, we always want cars corresponding to a given service header. (Notice, I still have no earthly idea what “service header” means, nor do I need to know.)&lt;/p&gt;
&lt;p&gt;Hey! I just did it again. I described &lt;strong&gt;the essential purpose&lt;/strong&gt; of &lt;code&gt;CarRepository&lt;/code&gt;: to decide which service header to use to find all the cars. This tells me that the tests should focus on searching on “the right” service header. I see two choices: let clients pass the service header into &lt;code&gt;CarRepository&lt;/code&gt; as a parameter, or force &lt;code&gt;CarRepository&lt;/code&gt; to decide on the service header itself. Guess what? The first option takes us back to what I’ve already done here. (All roads seem to lead to one place.) The second option changes things just a little.&lt;/p&gt;
&lt;p&gt;Let’s assume that &lt;code&gt;CarRepository&lt;/code&gt; encapsulates “the correct service header”—once again, &lt;em&gt;whatever that means&lt;/em&gt;. How do I know that &lt;code&gt;CarRepository&lt;/code&gt; has chosen wisely? I could ask it for its service header, but I see no other value in making &lt;code&gt;CarRepository&lt;/code&gt; do that, so I consider that my last resort.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; With the pieces available to me, I can detect which service header &lt;code&gt;CarRepository&lt;/code&gt; will use by… you guessed it… setting an expectation on the parameter it passes to &lt;code&gt;CarService.findAll()&lt;/code&gt;. Once again, I’ve described &lt;strong&gt;the essential interaction&lt;/strong&gt; between &lt;code&gt;CarRepository&lt;/code&gt; and &lt;code&gt;CarService&lt;/code&gt;: put “the right” service header in “the right place” at “the right time”. Once again: same tests, same reasons, &lt;strong&gt;except&lt;/strong&gt; perhaps a different emphasis, as reflected in subtle differences in naming.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void searchesForCarsWithTheRightServiceHeader() throws Exception {
  final Cars cars = new Cars(new Car(&amp;quot;irrelevant car name&amp;quot;));
  final ServiceHeader expectedServiceHeader = new ServiceHeader(&amp;quot;my guess at the correct properties for service header&amp;quot;);

  final CarService carService = mock(CarService.class);

  // Implicitly verifies that findAll() receives the correct argument
  when(carService.findAll(argThat(equalTo(expectedServiceHeader)))).thenReturn(cars);

  // The CarRepository encapsulates the service header
  final CarRepository carRepository = new CarRepository(carService);

  assertSame(cars, carRepository.findAll());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rather than playing “spot the differences”, I’ll enumerate them for you.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I renamed &lt;code&gt;serviceHeader&lt;/code&gt; to &lt;code&gt;expectedServiceHeader&lt;/code&gt; to emphasize checking that &lt;code&gt;CarRepository&lt;/code&gt; gets the service header “right”.&lt;/li&gt;
&lt;li&gt;I changed &lt;code&gt;verify()&lt;/code&gt; to check the parameter to &lt;code&gt;findAll()&lt;/code&gt; with &lt;code&gt;equals()&lt;/code&gt; instead of &lt;code&gt;==&lt;/code&gt;/&lt;code&gt;same()&lt;/code&gt;, because the instance of &lt;code&gt;ServiceHeader&lt;/code&gt; I &lt;em&gt;want&lt;/em&gt; to compare to remains trapped inside &lt;code&gt;CarRepository&lt;/code&gt; and I have no way to get a handle to it. (More on that in a moment.)&lt;/li&gt;
&lt;li&gt;I don’t pass &lt;code&gt;serviceHeader&lt;/code&gt; into the constructor for &lt;code&gt;CarRepository&lt;/code&gt;, but instead leave a comment to describe &lt;em&gt;why&lt;/em&gt; the test has to guess the service header. I’ve used a string to represent the service header, because Fabio’s article didn’t describe what makes service headers differ from one another. In the real code, we would put real service header attributes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Something bothers me about this test. I can express my consternation both in terms of intuition and mechanics.&lt;a href=&quot;#fn5&quot; class=&quot;footnote-ref&quot; id=&quot;fnref5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt; My intuition says, “I shouldn’t have to jump through all those hoops to know which service header to check for.” I look at the code and see that the service header I expect comes out of nowhere: I don’t see it anywhere in the input, nor anything that corresponds to it in the input, so I can’t account for why to expect it in the output. It works like magic.&lt;/p&gt;
&lt;p&gt;I do not like magic.&lt;/p&gt;
&lt;p&gt;What to do? I would prefer it if I could say something like &lt;em&gt;pretend that the &lt;code&gt;CarRepository&lt;/code&gt; chooses service header X; when it does, then I should expect parameter X when invoking &lt;code&gt;carService.findAll()&lt;/code&gt;&lt;/em&gt;. How do I implement this?&lt;/p&gt;
&lt;p&gt;If this doesn’t make you chuckle, then pay more attention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;. I don’t want to change the interface of &lt;code&gt;CarRepository&lt;/code&gt;, but I need a &lt;em&gt;seam&lt;/em&gt; so that I can override the service header. I can use Subclass to Test to do this.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void searchesForCarsWithTheRightServiceHeader() throws Exception {
  final Cars cars = new Cars(new Car(&amp;quot;irrelevant car name&amp;quot;));
  final ServiceHeader anyServiceHeader = new ServiceHeader();

  final CarService carService = mock(CarService.class);

  // Implicitly verifies that findAll() receives the correct argument
  when(carService.findAll(anyServiceHeader)).thenReturn(cars);

  // The CarRepository encapsulates the service header
  final CarRepository carRepository = new CarRepository(carService) {
    @Override
    protected ServiceHeader theServiceHeader() {
      return anyServiceHeader;
    }
  };

  assertSame(cars, carRepository.findAll());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll notice a few changes.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I don’t need to specify any special attributes in the service header any more, because I don’t need it to match whatever &lt;code&gt;CarRepository&lt;/code&gt; has chosen for itself, because I’ve overridden it anyway.&lt;/li&gt;
&lt;li&gt;I can go back to verifying the service header parameter with &lt;code&gt;==&lt;/code&gt;/same, rather than resorting to &lt;code&gt;equals()&lt;/code&gt;, because the test controls the instance of &lt;code&gt;ServiceHeader&lt;/code&gt; I expect to pass to &lt;code&gt;CarService.findAll()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I’ve renamed &lt;code&gt;expectedServiceHeader&lt;/code&gt; to &lt;code&gt;anyServiceHeader&lt;/code&gt;, because now I don’t care about the value of that instance, just as long as it &lt;em&gt;is&lt;/em&gt; a service header. Even &lt;code&gt;null&lt;/code&gt; would do, although that would carry other risks that I’d rather avoid.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I like this more, but not enough, because although my test now clearly describes the path from input to expected result, it now depends on knowing that &lt;code&gt;CarRepository&lt;/code&gt; gets its service header from &lt;code&gt;theServiceHeader()&lt;/code&gt;, rather than using the field directly. Oh no! Tautological TDD!&lt;/p&gt;
&lt;p&gt;We can’t leave it like this. We won’t. Calm down, Bob.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;. Let’s Replace Inheritance with Delegation&lt;a href=&quot;#fn6&quot; class=&quot;footnote-ref&quot; id=&quot;fnref6&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@Test
public void searchesForCarsWithTheRightServiceHeader() throws Exception {
  final Cars cars = new Cars(new Car(&amp;quot;irrelevant car name&amp;quot;));
  final ServiceHeader anyServiceHeader = new ServiceHeader();

  final CarService carService = mock(CarService.class);

  // Implicitly verifies that findAll() receives the correct argument
  when(carService.findAll(anyServiceHeader)).thenReturn(cars);

  final CarRepository carRepository = new CarRepository(carService, anyServiceHeader);

  assertSame(cars, carRepository.findAll());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks awfully familiar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;. Profit.&lt;/p&gt;
&lt;p&gt;Once again, all roads appear to lead to the same place. I don’t know what else to say here. The code wants me to design it this way, clearly, so I oblige it.&lt;/p&gt;
&lt;h3 id=&quot;uh-serviceheaderfactory&quot;&gt;Uh… &lt;code&gt;ServiceHeaderFactory&lt;/code&gt;?&lt;/h3&gt;
&lt;p&gt;Right. You probably noticed that I’ve ignored &lt;code&gt;ServiceHeaderFactory&lt;/code&gt; so far, and I hope that that bothered you a little. It bothered me. Fortunately, it doesn’t matter, because &lt;code&gt;ServiceHeaderFactory&lt;/code&gt; does nothing more than create a closure around &lt;code&gt;serviceHeader&lt;/code&gt;, so &lt;em&gt;nothing essential changes&lt;/em&gt; in any of the foregoing if you decide to replace &lt;code&gt;serviceHeader&lt;/code&gt; with &lt;code&gt;(() =&amp;gt; serviceHeader)()&lt;/code&gt;, or, if you’d like some names with your block of code—&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;new ServiceHeaderFactory() {
  public ServiceHeader create() {
    return serviceHeader;
  }
}.create()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It merely replaces a value with calling a function that returns that value. Potato, potato. You won’t hurt my feelings.&lt;/p&gt;
&lt;h2 id=&quot;tautological-no.-essential.&quot;&gt;Tautological? No. Essential.&lt;/h2&gt;
&lt;p&gt;I think I’ve done a few things here. You will have to judge how well.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Shown how easily one can conflate “tautological testing” (a definite risk in programmer testing) with “testing essential interactions” (an effective technique in programmer testing that guides design).&lt;/li&gt;
&lt;li&gt;Shown how clunky tests with mock objects can point to potential design flaws in production code. (I still think &lt;code&gt;CarRepository&lt;/code&gt; has to go.)&lt;/li&gt;
&lt;li&gt;Shown how sensible testing with mock objects and sensible modular design work hand-in-hand.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So there.&lt;/p&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;
&lt;p&gt;I totally lost count of the number of times I typed “Cat” and then replaced it with “Car” when I wrote this.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/the-curious-case-of-tautological-tdd/cats.png&quot; alt=&quot;Cats.&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Cats.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Eric Evans, &lt;a href=&quot;https://link.jbrains.ca/domain-driven-design-book&quot;&gt;&lt;em&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Erich Gamma and others. &lt;a href=&quot;https://link.jbrains.ca/11ATEqK&quot;&gt;&lt;em&gt;Design Patterns&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Martin Fowler and others, &lt;a href=&quot;https://link.jbrains.ca/32ZLFJJ&quot;&gt;&lt;em&gt;Refactoring: Improving the Design of Existing Code&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;  &lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Fabio Pereira, &lt;a href=&quot;https://link.jbrains.ca/RE9DUO&quot;&gt;“TTDD - Tautological Test Driven Development (Anti Pattern)”&lt;/a&gt;&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;A debugging technique not only makes it easy to spot mistakes, but also results in a minimal failing test for the mistake. https://www.infoq.com/news/2008/11/beck-saff-squeeze&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Fabio’s article does not divulge how to instantiate &lt;code&gt;CarService&lt;/code&gt;. It might involve deep magic.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;See? I don’t always add code “just for testing”.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn5&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Read more about how intuition and mechanics interact in my article, &lt;a href=&quot;https://link.jbrains.ca/gmeMhh&quot;&gt;“Becoming an Accomplished Software Designer”&lt;/a&gt;.&lt;a href=&quot;#fnref5&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn6&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;&lt;a href=&quot;#references&quot;&gt;&lt;em&gt;Refactoring&lt;/em&gt;&lt;/a&gt;, page 352.&lt;a href=&quot;#fnref6&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Wed, 14 May 2014 15:38:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-curious-case-of-tautological-tdd</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-curious-case-of-tautological-tdd</guid>
        
        
        <category>Simple Design</category>
        
        <category>Test Doubles</category>
        
      </item>
    
      <item>
        <title>Musings on Refactoring as Waste</title>
        <description>&lt;p&gt;Recently Bob Marshall opined that &lt;a href=&quot;https://link.jbrains.ca/1i63dIG&quot;&gt;refactoring code is waste&lt;/a&gt;. This reminds me of passionate discussions from a decade ago about testing: should we classify testing as a value-added activity or as an unavoidable waste? I’d like to change the question a little, but first, allow me to play the ball where it lies.&lt;/p&gt;
&lt;p&gt;If you haven’t read Bob’s article yet, then do so now. You’ll find it quite short; I read it in a few minutes. &lt;em&gt;I composed this as a comment to Bob’s article, but it expanded to the point where I chose to promote it to a short article. You might say that I refactored my writing. With that segue manufactured…&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Is editing waste for a writer? Why don’t writers simply write the right words/articles/books/sentences the first time? So I think it goes for programmers. I think of refactoring as editing for programmers. Since I plan to refactor, I don’t have to program like Mozart and “get it right” in my head before writing it down. This helps me, because often I don’t see trouble with code until I’ve written it down, even though sometimes drawing its structure helps me enough to spot trouble.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sometimes problems don’t emerge until long after I’ve written it down and the situation changes, putting pressure on an old choice or negating an old assumption. Absolutely/permanently right-first-time seems to require clairvoyance. Writing any code entails risk.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Even so, I agree that we programmers don’t need to deny our own experience just to fit some arbitrary goal of taking tiny steps and refactoring towards abstractions. (This has got me in trouble with some people who declare what I do “not TDD”. As they wish.) Sometimes I can see the abstractions, so I go there sooner. Sometimes that doesn’t work out, so I refactor towards different abstractions. Often it works out and I’ve skipped a handful of tedious intermediary steps. One could measure my “expertise” in design by measuring the additional profit I can squeeze out of these trade-offs compared to others. (No, I don’t know how to measure that directly.) I think we broadly call that “judgment”.&lt;/p&gt;
&lt;h2 id=&quot;a-question-of-intent&quot;&gt;A Question of Intent&lt;/h2&gt;
&lt;p&gt;I find refactoring wasteful when I do it out of habit, rather than with a purpose. Nevertheless, I don’t know how to have developed the judgment to know the difference without making a habit of refactoring. (Of course, I like to think that I do everything always with a purpose.) I encourage novices (in the &lt;a href=&quot;https://bit.ly/dreyfus-novice&quot;&gt;Dreyfus Model&lt;/a&gt; sense) to force code into existence primarily through refactoring with the purpose of developing that judgment and calling into question their assumptions about design. That reasoning sounds circular, but I have &lt;a href=&quot;/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;written and said elsewhere&lt;/a&gt; how refactoring helps programmers smooth out the cost of maintaining a system over time. I can only assert that I produce more maintainable software this way, compared to what I used to do, and that refactoring plays a role. I really wish I knew how much of that improvement to attribute to refactoring. Refactoring still saves my ass from time to time, so it must pull some of its own weight.&lt;/p&gt;
&lt;p&gt;I would classify refactoring as waste in the same way that I’d classify verification-style testing as waste: since we don’t work perfectly, we need feedback on the fitness of our work. Not only that, but I refactor to support not having to future-proof my designs, because of the waste of building structures now that we don’t intend to exploit until later. Which waste costs more? I find that open question quite interesting.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Bob Marshall, &lt;a href=&quot;https://link.jbrains.ca/1i63dIG&quot;&gt;“Code Refactoring”&lt;/a&gt;. In his article, Bob surmises that programmers can’t quite “get it right” in their heads, and highlights refactoring as potentially a self-fulfilling waste: if we assume that we have to live with it, then we will choose to live with it. I leave the parallel with &lt;a href=&quot;https://link.jbrains.ca/1i66gRd&quot;&gt;#NoEstimates&lt;/a&gt; as an exercise for the reader.&lt;/p&gt;
&lt;p&gt;Gemma Cameron, &lt;a href=&quot;https://link.jbrains.ca/1i66mIg&quot;&gt;“Is Refactoring Waste?”&lt;/a&gt;. I noticed Gemma’s article on Twitter and it led me to read Bob’s. She mentions that she plans to experiment with a TDD microtechnique that I use often: noticing while ‘on red’ that a little refactoring would make it easier to pass the test, and so ignoring (or deleting) the test to get back to ‘green’ in order to refactor safely. I don’t always do this, but I consider it part of the discipline of TDD and teach it in my training courses.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bit.ly/dreyfus-novice&quot;&gt;“The Dreyfus Model of Skill Acquisition”&lt;/a&gt;. Wikipedia’s introduction to the topic. All models are wrong; some models are useful. I find this one helpful in explaining to people the various microtechniques that I teach, when I follow them and when I don’t.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;“The Eternal Struggle Between Business and Programmers”&lt;/a&gt;. The article in which I make the case for refactoring as a key element in reducing the cost of adding features to a system over time.&lt;/p&gt;
</description>
        <pubDate>Tue, 22 Apr 2014 12:39:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/musings-on-refactoring-as-waste</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/musings-on-refactoring-as-waste</guid>
        
        
      </item>
    
      <item>
        <title>Google Spreadsheet as a Test-First Demo Environment</title>
        <description>&lt;p&gt;If you like to teach test-first/test-driven techniques, then you have probably stumbled over configuration problems in your programming environment. This happens to every presenter at least once. We have a variety of ways to handle the problem, and today I’d like to share another one with you.&lt;/p&gt;
&lt;p&gt;Google Spreadsheet can run Javascript, which means that we now have a ready-to-go approximation of &lt;a href=&quot;https://fit.c2.com&quot;&gt;Fit&lt;/a&gt;. It took me only a few minutes to figure out how to write a Javascript function that operates on the value in a spreadsheet cell. After that, I recorded ten minutes of video demonstrating the environment.&lt;/p&gt;
&lt;figure class=&quot;body-text-block&quot;&gt;
&lt;div class=&quot;embedded-video-container&quot;&gt;
&lt;iframe class=&quot;embedded-video&quot; src=&quot;https://www.youtube.com/embed/Bk1am07r8zQ?rel=0&quot; frameborder=&quot;0&quot; allow=&quot;encrypted-media&quot; allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;Yes, I wrote the code test-first, but not test-driven. Please hold your cards and letters. I wanted to demonstrate a testing environment and not TDD. Even so, with ATDD or BDD, we programmers often receive a batch of customer tests and make them pass one by one, and sometimes we don’t need additional programmer tests to have confidence that we’ve built things well. Looking at the final design for this solution, I don’t think that a strict test-driven approach would have improved anything. If you disagree, then please share your approach with us!&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 25 Mar 2014 10:01:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/google-spreadsheet-as-a-test-first-demo-environment</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/google-spreadsheet-as-a-test-first-demo-environment</guid>
        
        
      </item>
    
      <item>
        <title>Putting An Age-Old Battle To Rest</title>
        <description>&lt;p&gt;So maybe not an &lt;em&gt;epic&lt;/em&gt;, age-old battle, but a battle nonetheless. The battle over the correct ordering of the &lt;a href=&quot;https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;Four Elements of Simple Design&lt;/a&gt;. A battle that I’ve always known I’d won, but until recently, could never justify to others. I can finally declare victory and bestow upon you the One True Sequence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Calm down; I’m joking.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Seriously: it has always bothered me (a little) that I say it &lt;em&gt;this way&lt;/em&gt; and Corey Haines says it &lt;em&gt;that way&lt;/em&gt;, and somehow we both have it “right”. I never quite understood how that could happen… until now.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;figure style=&quot;width: 200px; max-width: 35%; float: right; margin-left: 1em; margin-bottom: 1em&quot;&gt;
&lt;a href=&quot;https://www.amazon.com/How-Write-Good-Programs-Students-ebook/dp/B08BKY8S1X/ref=as_li_ss_tl?&amp;linkCode=ll1&amp;tag=jbrains.ca-20&amp;linkId=50fbe9d87e626c306ab7de9a0aa03a52&amp;language=en_US&quot;&gt;&lt;img src=&quot;/images/Cover-how-to-write-good-programs.jpg&quot; /&gt;
&lt;figcaption&gt;
This article is featured in Perdita Stevens’ textbook, &lt;em&gt;How To Write Good Programs&lt;/em&gt;
&lt;/figcaption&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;I learned these “rules” of simple design—guidelines, really—from the work of Kent Beck. He suggested the following guidelines as a definition of “simple”.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; He calls code “simple” if it:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;passes its tests&lt;/li&gt;
&lt;li&gt;minimises duplication&lt;/li&gt;
&lt;li&gt;reveals its intent&lt;/li&gt;
&lt;li&gt;has fewer classes/modules/packages…&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;He mentioned that passing tests matters more than low duplication, that low duplication matters more than revealing intent, and that revealing intent matters more than having fewer classes, modules, and packages.&lt;/p&gt;
&lt;p&gt;I grew up (as a programmer) with these rules, and they have guided me well. My friend and colleague, &lt;a href=&quot;https://www.twitter.com/coreyhaines&quot;&gt;Corey Haines&lt;/a&gt;, however, obstinately insists on reversing the order of “remove duplication” and “reveal intent”. He presents the four elements of simple design this way:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;pass the tests&lt;/li&gt;
&lt;li&gt;reveal intent&lt;/li&gt;
&lt;li&gt;don’t repeat yourself&lt;/li&gt;
&lt;li&gt;fewer classes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Corey hasn’t cornered the market on interpreting Beck’s rules in this order. If you search the web, you’ll find a surprising number of articles about the four elements of simple design advocating either sequence of rules. Some articles probably even argue quite loudly in support of ordering the rules one way or the other.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I have finally figured out why this happens&lt;/strong&gt;. At least, I &lt;em&gt;think&lt;/em&gt; I have. And I have good news: &lt;strong&gt;we all have it wrong&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I don’t think it matters whether you focus first on removing duplication or on revealing intent/increasing clarity, because these two guidelines very quickly form a rapid, tight feedback cycle. By the time the guidelines guide you to any useful results, you’ll have probably used them both. &lt;strong&gt;Therefore, order the rules however you like, because you’ll get to the same place either way.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nice, isn’t it?&lt;/p&gt;
&lt;h2 id=&quot;what-i-think-happens&quot;&gt;What I Think Happens&lt;/h2&gt;
&lt;p&gt;I have noticed over the years that when I try to focus on removing duplication, new, useful structures emerge. I like to say that if the solution wants to be structured a certain way, then removing duplication helps that structure to emerge.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; I have also noticed that when I try to focus on &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;improving names&lt;/a&gt;, Feature Envy and its friends become more apparent, and code makes it clearer that it wants to move somewhere else. Similar concepts scattered throughout the system start calling out to each other, hoping for the programmer to unite them in a single module. Crowded, unrelated concepts struggle to get away from one another. Responsibilities gradually move to a more sensible part of the code base. Both of these contribute to &lt;a href=&quot;https://link.jbrains.ca/11hmmkp&quot;&gt;higher cohesion&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/age_old_battle/rules_improve_cohesion.png&quot; /&gt;
&lt;figcaption&gt;
How rules 2 and 3 improve cohesion
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;But wait; there’s more&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Whenever we create new structures in code—extracting methods, functions, classes, modules—we have to give these new structures names. We never really like these names, so we always seek to &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;improve them&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/age_old_battle/new_structures_need_names.png&quot; /&gt;
&lt;figcaption&gt;
Structures need names, which we need to improve
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As the names improve, cohesion improves, so that similar things move closer together and different things move farther apart. Removing duplication creates buckets and &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;improving names&lt;/a&gt; redistributes the things among the buckets. Over time, the rest of the system—the clients of these buckets—treat the buckets more like single things rather than collections of things. We call this &lt;strong&gt;abstraction&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/age_old_battle/abstractions_emerge.png&quot; /&gt;
&lt;figcaption&gt;
Better names lead to bigger abstractions
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But, of course, at this higher level of abstraction, we get away from &lt;em&gt;those&lt;/em&gt; details and start seeing new patterns in bigger things. That means more duplication.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/age_old_battle/more_duplication_becomes_visible.png&quot; /&gt;
&lt;figcaption&gt;
Bigger abstractions help us see more, bigger duplication
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We see duplication, then we remove it. We need to give these new structures names. We want to improve those names. In the process, more details slip away and more abstractions emerge. We raise the level of abstraction again.&lt;/p&gt;
&lt;p&gt;And again.&lt;/p&gt;
&lt;p&gt;And again.&lt;/p&gt;
&lt;p&gt;This describes a way to organize code into helpful layers with beneficial abstractions, rather than leaky indirection. When we remove duplication, we create buckets; when we improve names, we create more cohesive, more easily-abstracted buckets. &lt;strong&gt;We need them both&lt;/strong&gt; and &lt;strong&gt;we just keep going&lt;/strong&gt;. I don’t see a big difference when I start by removing duplication, compared to when I start by &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;improving names&lt;/a&gt;.&lt;/p&gt;
&lt;figure id=&quot;simple-design-dynamo&quot;&gt;
&lt;img src=&quot;/images/age_old_battle/virtuous_cycle.png&quot; /&gt;
&lt;figcaption&gt;
The Simple Design Dynamo&lt;sup&gt;TM&lt;/sup&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;the-four-elements-of-simple-design-revisited&quot;&gt;The Four Elements of Simple Design Revisited&lt;/h2&gt;
&lt;p&gt;I have been teaching for years about how to reduce the four elements of simple design to two: after several months, I don’t think about writing tests any more—I simply call that “programming”—and I’ve never seen a well-factored code base that had an order of magniture too many elements. With these two points out of the way, I guide my design with two basic rules: &lt;strong&gt;remove duplication&lt;/strong&gt; and &lt;strong&gt;improve names&lt;/strong&gt;. I’ve started thinking about these guidelines a little differently.&lt;/p&gt;
&lt;p&gt;Now, I think of them as a single guideline: &lt;strong&gt;remove duplication and improve names in small cycles&lt;/strong&gt;. When I do this, I produce a higher proportion of well-factored code compared to all the code I write. I use tests to clarify the goal of my code and to put strict limits on how much code I write.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
Tests help me limit the amount of code that I write. Removing duplication and &lt;a href=&quot;/permalink/a-model-for-improving-names&quot;&gt;improving names&lt;/a&gt; helps me reduce the liability (cost) of the code that I write. Together, they help me reduce both the total cost and the volatility of the cost of the features I deliver.
&lt;/p&gt;
&lt;p&gt;I think this suffices as a working definition of “writing the code right”, which complements the need to “write the right code”. I have a whole bag of tricks to help do this well, which I call &lt;a href=&quot;https://value-driven-product-development.jbrains.ca&quot;&gt;&lt;del&gt;Product Sashimi&lt;/del&gt; Value-Driven Product Development&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;reactions&quot;&gt;Reactions&lt;/h2&gt;
&lt;p&gt;Of course, just as I use Corey as the poster child for “getting it wrong”, he makes me look like a sore winner.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;&lt;/a&gt; Yup! I try to emphasize to people that rules 2 and 3 build on each other and you need to iterate. Doesn&apos;t matter which is first.
&lt;/p&gt;
— Corey Haines (&lt;span class=&quot;citation&quot; data-cites=&quot;coreyhaines&quot;&gt;@coreyhaines&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/coreyhaines/statuses/409439183963299840&quot;&gt;December 7, 2013&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;He goes on to say this.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;https://twitter.com/angelaharms&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;angelaharms&quot;&gt;@angelaharms&lt;/span&gt;&lt;/a&gt; &lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;&lt;/a&gt; Honestly, I always have a hard time remembering which one is 2, which is 3, so I just sort of right them however.
&lt;/p&gt;
— Corey Haines (&lt;span class=&quot;citation&quot; data-cites=&quot;coreyhaines&quot;&gt;@coreyhaines&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/coreyhaines/statuses/409439447508205568&quot;&gt;December 7, 2013&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;He also has a hard time writing “write”, but we love him just the same.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/dSCPE6&quot;&gt;“Three Steps to a Useful Minimal Feature”&lt;/a&gt;. This article describes one of the key techniques of Product Sashimi.&lt;/p&gt;
&lt;p&gt;Kent Beck, &lt;a href=&quot;https://link.jbrains.ca/UNqq44&quot;&gt;Extreme Programming Explained&lt;/a&gt;. Where I first learned these rules of simple design.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I use “simple” as shorthand for “lowers the cost of future features”. For more, watch &lt;a href=&quot;https://link.jbrains.ca/1biOFRU&quot;&gt;“The Economics of Software Development”&lt;/a&gt; or, if you prefer to read, I plan to write more about this at &lt;a href=&quot;https://blog.jbrains.ca&quot;&gt;jbrains.ca&lt;/a&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Thus, “your code is trying to tell you something”.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sat, 07 Dec 2013 03:50:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest</guid>
        
        
        <category>Improving Names</category>
        
      </item>
    
      <item>
        <title>Beyond Mock Objects</title>
        <description>&lt;p&gt;You might call this title “clickbait”. Yes and no. Of course, I want you to read this article, but at the same time, there is no bait and switch here. I use test doubles (“mock objects”, since that term refuses to die) freely and happily. I use them prominently as design tools. I like them. I feel grateful to them. And even so, my design sometimes improves when I remove them. To paraphrase Ron Jeffries, &lt;strong&gt;this is good news about the improved design and not bad news about test doubles&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Herein, I rely on the general principle that &lt;strong&gt;increasing testability tends to improve design, and in particular, helps us deliver features less expensively and with more predictable cost&lt;/strong&gt;. If you don’t believe that, then what follows will likely not interest you.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; I tend to get better results by writing &lt;strong&gt;repeatable&lt;/strong&gt; tests, meaning that &lt;strong&gt;running the same test several times without any code changes gives the same result (pass or fail)&lt;/strong&gt;. Repeatable tests earn my trust by detecting potentially-breaking changes in my code rather than bothering me with incidental changes in the runtime environment. This leads me to adopt a guideline about repeatability.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Write more repeatable tests. (Tests with more repeatability &lt;em&gt;and&lt;/em&gt; more of them.)
&lt;/p&gt;
&lt;h2 id=&quot;threats-to-repeatability&quot;&gt;Threats to Repeatability&lt;/h2&gt;
&lt;p&gt;Certain design decisions threaten repeatability, such as depending on externalized configuration data, databases, web services, the location of certain files containing expected content, and even the layout of the file system (Windows or Unix). All these external dependencies threaten to &lt;strong&gt;change the results of a test run even though the underlying production code has not changed&lt;/strong&gt;. These choices make it more difficult to reason about the code, to find the source of a mistake, or to assess the impact of a change, because the behavior of the system could change without warning. &lt;strong&gt;While &lt;a href=&quot;/permalink/the-pain-of-implicit-dependencies&quot;&gt;implicit dependencies&lt;/a&gt; hurt, implicit dependencies on unstable resources hurt even more&lt;/strong&gt;. In order to write more repeatable tests, I limit the amount of code that depends on unstable resources.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Unstable dependencies threaten repeatability. Implicit dependencies threaten our reasoning about the code. Unstable, implicit dependencies threaten our sanity.
&lt;/p&gt;
&lt;h2 id=&quot;one-uncommonly-common-unstable-dependency&quot;&gt;One Uncommonly Common Unstable Dependency&lt;/h2&gt;
&lt;p&gt;We work quite frequently with one common unstable dependency: the system clock. When we write code that depends on a random-number generator, we depend indirectly on the system clock. When we write code that needs a timestamp or two, we often write code that depends directly on the system clock. We find it so easy to use: it has become an informal, unspoken convention that creating a timestamp value defaults that value to “now” (or “today”). Programmers so routinely depend on this behavior that it bears responsibility for one of the most pervasive implicit dependencies in the world of software. Not merely pervasive but, as almost every programmer eventually discovers, insidious—at least when they decide that they’d like to write automated tests.&lt;/p&gt;
&lt;p&gt;The average programmer will have written Transaction Scripts (see the &lt;a href=&quot;#references&quot;&gt;references&lt;/a&gt; below to learn more about this topic) in web applications that retrieve, for example, all the customers with orders placed in the preceding seven days, a straightforward version of which looks like the following Python-like code. (&lt;em&gt;Not intended to be working nor optimized code, but lovingly improved with the help of George Paci.&lt;/em&gt;)&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;A straight-forward implementation; you&amp;#39;ve probably also written this before&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def handle_request(self, request, response):
    now = Date()
    seven_days_ago = now - 7 * 24 * 60 * 60 * 1000 # in milliseconds
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, now))
    # The ModelAndView pattern, inspired by Spring Web MVC
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The line &lt;code&gt;now = Date()&lt;/code&gt; interests me, because I see at least two problems with it. Superficially, it obscures the way to compute &lt;code&gt;now&lt;/code&gt;, and so I’d prefer at least to write it as &lt;code&gt;Date.today()&lt;/code&gt; or &lt;code&gt;Timestamp.now()&lt;/code&gt;. More significantly, however, it also creates a &lt;em&gt;direct, hardwired dependency on an unstable, global resource&lt;/em&gt;: the system clock. &lt;strong&gt;We can almost never run this code twice and get the same result&lt;/strong&gt;, at least not without considerable effort. (I’m waiting for the day that someone includes “set the time to 14:30” in their &lt;code&gt;puppet&lt;/code&gt; instructions.)&lt;/p&gt;
&lt;p&gt;“No problem!”, you shout with delight. &lt;a href=&quot;https://link.jbrains.ca/1i3ts3H&quot;&gt;Dependency Injection&lt;/a&gt; to the rescue! We shall use the Virtual Clock pattern! Yes, we absolutely can, and I still think fondly of Paolo Perrotta’s delightful article on the topic—an article which influenced my early understanding of testability and design. This article had disappeared for a while, but &lt;a href=&quot;https://ducktypo.blogspot.com/2013/12/the-virtual-clock-test-pattern.html&quot;&gt;Paolo republished it&lt;/a&gt; in 2013 and included &lt;a href=&quot;https://web.archive.org/web/20031002130021/https://www.nusco.org/docs/virtual_clock_draft1.pdf&quot;&gt;a reference to the original, courtesy of the Wayback Machine&lt;/a&gt;. Even so, let me summarize the pattern for you.&lt;/p&gt;
&lt;h2 id=&quot;the-virtual-clock&quot;&gt;The Virtual Clock&lt;/h2&gt;
&lt;p&gt;Don’t depend on the system clock directly, but instead inject an interface &lt;code&gt;Clock&lt;/code&gt; that we can simulate in tests and implement in production to talk to the system clock. ISP and DIP together..&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;Using the Virtual Clock&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def __init__(orders_repository, clock):
    self.orders_repository = orders_repository
    self.clock = clock or SystemClock.new # in case clock is None

  def handle_request(self, request, response):
    now = self.clock.now()
    seven_days_ago = now - 7 * 24 * 60 * 60 * 1000
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= %d and created_at &amp;lt;= %d&amp;quot; % (seven_days_ago, now))
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we introduce an interface (or protocol, in the case of languages without explicit interfaces, like Python) representing a clock with the appropriate methods.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;The Clock protocol with both a test double and a production implementation&quot;&gt;&lt;code&gt;# One way to implement Clock in tests, especially for programmers
# who don&amp;#39;t like test double libraries
class FrozenClock:
  def __init__(current_time_millis):
    self.current_time_millis = current_time_millis

  def now(self):
    Date(self.current_time_millis)

# A typical production implementation
class SystemClock:
  def __init__():
    pass  # I&amp;#39;ll just talk to the system clock directly as a global resource, if you don&amp;#39;t mind

  # Improving the name as well as breaking the dependency
  def now(self):
    Date()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this new protocol, we can easily freeze the clock to any time that our various tests find convenient. &lt;em&gt;You could stub the &lt;code&gt;Clock&lt;/code&gt; interface with your favorite test double library, if you prefer.&lt;/em&gt; The Virtual Clock solves the repeatability problem.&lt;/p&gt;
&lt;h2 id=&quot;something-smells&quot;&gt;Something Smells&lt;/h2&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;the resulting code exposes details rather than hiding them&quot;&gt;&lt;/span&gt; In spite of this, something feels wrong about the design. The code has become more flexible, but also more complicated, and I don’t feel&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; particularly good about the dependency that we’ve introduced. We’ve made an implicit dependency more explicit, and I value that a lot, but &lt;code&gt;Clock&lt;/code&gt; somehow feels like &lt;strong&gt;indirection without abstraction&lt;/strong&gt;. By this I mean that we’ve introduced a &lt;em&gt;seam&lt;/em&gt;&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; to improve testability, but that the resulting code exposes details rather than hiding them, and &lt;strong&gt;abstractions, by definition, hide details&lt;/strong&gt;. This looks like the kind of indirection that makes experienced designers look at testability nuts like us with suspicion. Rightly so, I have begun to conclude.
&lt;/p&gt;
&lt;p&gt;I used to think that “they” had it wrong. I even felt really confident about that. Now I see their point better.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
If we want to introduce indirection, then we ought to introduce the smallest indirection possible. And we &lt;strong&gt;absolutely must try&lt;/strong&gt; to introduce better abstraction.
&lt;/p&gt;
&lt;p&gt;Indirection costs: it adds code, it adds cognitive load, it adds complications, and &lt;a href=&quot;/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;complications kill&lt;/a&gt;. I prefer to keep those costs low. In this example, &lt;code&gt;Clock&lt;/code&gt; feels to me like an artificial “abstraction”, and as a result, I’d rather do something else. Many programmers, in this situation, blame abstraction in general for this situation, calling it “over-engineering”, but I don’t. Instead, I interpret it as a signal to look for a more-suitable abstraction, which I eventually find. A “more-suitable” abstraction hides the annoying details and exposes only the essentials. Sometimes a detail looks essential at first and later becomes annoying. &lt;strong&gt;This reflects changes in my understanding of the code, the design, the domain, or the system, and not a failure of abstraction!&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;where-are-my-keys&quot;&gt;Where Are My Keys?&lt;/h3&gt;
&lt;p&gt;Imagine that I want to hand you my keys, and that you stand right next to me. In order to give you my keys, I walk to another room on another floor, put my keys on the table, walk back, then tell you, “You’ll find my keys on the table in room 417.” When we introduce &lt;code&gt;Clock&lt;/code&gt; in order to provide a timestamp to our Transaction Script, we do this: we give that Transaction Script instructions to find the timestamp that it needs. I don’t think that helps us here.&lt;/p&gt;
&lt;aside class=&quot;aside&quot;&gt;
Wait a second… this dude has written about dependency injection in the past. We &lt;em&gt;know&lt;/em&gt; that he’s a TDD nut. He can’t possibly be telling us to &lt;a href=&quot;https://link.jbrains.ca/1653RlF&quot;&gt;defactor&lt;/a&gt; and write &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;integrated tests&lt;/a&gt;!
&lt;/aside&gt;
&lt;h2 id=&quot;dont-inject-what-you-could-ignore&quot;&gt;Don’t Inject What You Could Ignore&lt;/h2&gt;
&lt;p&gt;You’ve probably heard this before: don’t automate what you could eliminate. Similarly:&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Don’t inject what you could ignore.
&lt;/p&gt;
&lt;p&gt;Do we want a clock? I don’t. Do you? No. So why inject &lt;code&gt;Clock&lt;/code&gt;? We don’t want a clock; we want a timestamp. We really only want the clock because we want &lt;code&gt;now&lt;/code&gt;. We could take a page from our functional programming friends and inject a function that eliminates the assumption that one obtains a timestamp from a clock.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;Don&amp;#39;t send a protocol to do a function&amp;#39;s job&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def __init__(orders_repository, now = lambda: Date()):
    self.orders_repository = orders_repository
    self.now = now

  def handle_request(self, request, response):
    now = self.now() # self.now.call() in some languages
    seven_days_ago = now - 7 * 24 * 60 * 60 * 1000
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, now))
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This seems like an improvement, but I think it really represents a mere difference in syntax. Yes, we avoid a class and a constructor, but a one-function protocol and a lambda expression can do exactly the same job, except that the protocol’s function has an explicit name. The protocol describes itself better, but the lambda expression provides more flexibility and arguably follows ISP better. Whichever we choose, injecting the behavior provides the real value, by allowing clients to do whatever they need: tests inject a lambda that returns a hardcoded timestamp, while the production implementation injects a reference to the system clock. In C# we would use a delegate and even Java has had lambda expressions for years now. Even so, I think we can do better.&lt;/p&gt;
&lt;h2 id=&quot;a-minor-problem&quot;&gt;A Minor Problem&lt;/h2&gt;
&lt;p&gt;This code respects the &lt;a href=&quot;https://en.wikipedia.org/wiki/Interface_segregation_principle&quot;&gt;Interface Segregation Principle&lt;/a&gt; better, but it still suffers from a serious design problem that could trip you up during a heated, future refactoring session. Imagine what would happen if you tried to inline the temporary variable &lt;code&gt;now&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;That&amp;#39;s a mistake&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def __init__(orders_repository, now = lambda: Date()):
    self.orders_repository = orders_repository
    self.now = now

  def handle_request(self, request, response):
    seven_days_ago = self.now() - 7 * 24 * 60 * 60 * 1000 # inlined here
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, self.now())) # and here
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you invoke &lt;code&gt;now()&lt;/code&gt; more than once, you’ll get a different value for &lt;code&gt;now&lt;/code&gt; each time. At some point, this will cause a problem. This is exactly the kind of situation that motivates programmers to conclude that “mocking means depending on implementation details”. Well, yes and no. Even deeper than this: storing state breaks the Substitution Model of computing. Sometimes we need to store state, but as our functional programing friends continually remind us, we benefit from doing that &lt;em&gt;as little as we can&lt;/em&gt;.&lt;/p&gt;
&lt;aside class=&quot;aside&quot;&gt;
Before you label this an artificial problem, consider how frequently we extract and inline code when we refactor, and that because we do this so often, we sometimes forget that inlining a temporary variable introduces mistakes when the operation that we assign to that variable doesn’t behave with referential transparency&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;. This particular code will almost always work correctly, but as soon as those two invocations of &lt;code&gt;self.now()&lt;/code&gt; straddle midnight, we risk having &lt;em&gt;eight&lt;/em&gt; days of orders rather than seven. We don’t know that this represents a bug, but it definitely represents an issue.&lt;a href=&quot;#fn5&quot; class=&quot;footnote-ref&quot; id=&quot;fnref5&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt; Even if the risk remains low, we don’t need to have introduced this risk at all. We can do better.
&lt;/aside&gt;
&lt;p&gt;Of course, we solve this problem by introducing a temporary variable to store the value of &lt;code&gt;now&lt;/code&gt; right at the beginning of the function.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There’s a clue in that sentence!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You pass me a clock, and I immediately ask it for the one timestamp that I need, and then never talk to the clock again. So why exactly did you pass me a clock?!&lt;/p&gt;
&lt;h2 id=&quot;dont-inject-what-you-could-ignore-redux&quot;&gt;Don’t Inject What You Could Ignore Redux&lt;/h2&gt;
&lt;p&gt;Why inject a function returning &lt;code&gt;12&lt;/code&gt; when we could merely “inject” &lt;code&gt;12&lt;/code&gt;? Yes, in the future, we might need to inject something that computes &lt;code&gt;12&lt;/code&gt;, but for now, we just need the &lt;code&gt;12&lt;/code&gt;, so we owe it to ourselves to try injecting &lt;code&gt;12&lt;/code&gt; and seeing how that changes our perception of the design.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;12&lt;/code&gt;. (Annoyed yet?)&lt;/p&gt;
&lt;p&gt;I’ll &lt;em&gt;defactor&lt;/em&gt; this code just a little more and you’ll probably find it strange.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;Don&amp;#39;t send a function to do a value&amp;#39;s job&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def __init__(orders_repository, now):
    self.orders_repository = orders_repository
    self.now = now or Date() # in case now is None

  def handle_request(self, request, response):
    seven_days_ago = self.now - 7 * 24 * 60 * 60 * 1000
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, self.now))
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I find it strange, too. I’ve simplified the dependency in one respect, and complicated it in another: clients have to instantiate a new controller on each request, or said differently, the controller has &lt;em&gt;request scope&lt;/em&gt;. This sounds wrong.&lt;/p&gt;
&lt;p&gt;Moreover, one typically doesn’t “inject” values; one simply passes them as parameters.&lt;a href=&quot;#fn6&quot; class=&quot;footnote-ref&quot; id=&quot;fnref6&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt; It should pose no problem, then, to reduce the scope of &lt;code&gt;now&lt;/code&gt; to the method… except that we live in a framework—didn’t I mention that?—where we have to implement the method &lt;code&gt;handle_request(self, request, response)&lt;/code&gt; in order to register our controller to receive requests for the URI &lt;code&gt;/customers/recent_orders&lt;/code&gt;. This limitation creates tension: I want &lt;code&gt;now&lt;/code&gt; as a parameter to the request handler, but the framework doesn’t want to (and couldn’t possibly) know this domain-level detail. (Or could it? Think about it.) This encourages me to extract a new method as a compromise.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def __init__(orders_repository):
    self.orders_repository = orders_repository

  def handle_request(self, request, response):
    return handle_request_as_of(self, request, response, Date())

  def handle_request_as_of(self, request, response, now):
    seven_days_ago = now - 7 * 24 * 60 * 60 * 1000
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, now))
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Brace yourself: &lt;strong&gt;I probably wouldn’t test &lt;code&gt;handle_request()&lt;/code&gt;&lt;/strong&gt;. &lt;a href=&quot;https://junit.org/junit4/faq.html#best_3&quot;&gt;Don’t panic&lt;/a&gt;. I would test &lt;code&gt;handle_request_as_of()&lt;/code&gt; with great care and attention and then trust that I typed &lt;code&gt;Date()&lt;/code&gt; correctly. This change would improve the design in one obvious way: I could test &lt;code&gt;handle_request_as_of()&lt;/code&gt; quite easily, by passing a variety of values for &lt;code&gt;now&lt;/code&gt;. Moreover, we could improve the name &lt;code&gt;now&lt;/code&gt;, replacing it with something less context dependent, and call it &lt;code&gt;instant&lt;/code&gt;. (This reflects Joda Time’s influence on me, an accident of history, rather than some deep understanding about the domain of timekeeping.)&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;We can name this parameter with an eye towards reuse&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController:
  def __init__(orders_repository):
    self.orders_repository = orders_repository

  def handle_request(self, request, response):
    return handle_request_as_of(self, request, response, Date())

  def handle_request_as_of(self, request, response, instant):
    seven_days_ago = instant - 7 * 24 * 60 * 60 * 1000
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, instant))
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I choose to ignore for the moment the issue with assuming that &lt;code&gt;instant&lt;/code&gt; is a number representing time in milliseconds. If you and I paired on this for a real client, we’d have fixed that by now, so that the code could read something more like &lt;code&gt;instant.minus(Days(7))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I like that this new method now finds “customers with recent open orders, relative to any date you choose”, rather than specifically relative to &lt;strong&gt;now&lt;/strong&gt;. Come to think of it, “recent” now feels a little out of place. So does “ago”, which should become “prior” or “before”. I digress. The names matter, and we would fix them, but I want this article to focus on the emerging abstraction.&lt;/p&gt;
&lt;h2 id=&quot;the-instantaneous-request&quot;&gt;The Instantaneous Request&lt;/h2&gt;
&lt;p&gt;We have given birth to a new abstraction in our web application framework: &lt;strong&gt;the instantaneous request&lt;/strong&gt;. This object represents a request that we handle by pretending that it happens all at once (instantaneously). I expect us to find this abstraction useful in other parts of the system. We might even extract it into a request handler Decorator that we could use more widely. Of course, I would encourage us to wait until we had three instantaneous requests before we extracted the duplication, and when we did, we’d have something like the following.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# Reuse me!
class InstantaneousRequestController:
  def __init__(instantaneous_request):
    self.instantaneous_request = instantaneous_request

  def handle_request(self, request, response):
    self.instantaneous_request.handle_request_as_of(self, request, response, Date())

# I belong to the domain
class CustomersWithOpenOrdersAsOfInstantController:
  def __init__(orders_repository):
    self.orders_repository = orders_repository

  def handle_request_as_of(self, request, response, instant):
    seven_days_ago = instant - 7 * 24 * 60 * 60 * 1000
    recent_open_orders = self.orders_repository.find_all_open_orders(&amp;quot;created_at &amp;gt;= date(%d) and created_at &amp;lt;= date(%d)&amp;quot; % (seven_days_ago, instant))
    response.attributes[&amp;quot;customers_with_recent_open_orders&amp;quot;] = recent_open_orders.map(lambda order: order.customer).uniq
    response.view = &amp;quot;RecentOpenOrdersReport&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When it came time to register this controller to respond to the appropriate request URI, that would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;InstantaneousRequestController(
  CustomersWithOpenOrdersAsOfInstantController(
    ProductionCaliberOrdersRepository()))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’d feel more comfortable giving this a name, then feel free.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-caption=&quot;Giving a name to our newest creation&quot;&gt;&lt;code&gt;class CustomersWithRecentOpenOrdersController(InstantaneousRequestController):
  def __init__(orders_repository):
    super(CustomersWithOpenOrdersAsOfInstantController(orders_repository))&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;the-whole-point&quot;&gt;The Whole Point&lt;/h2&gt;
&lt;p&gt;Did you notice the comment &lt;code&gt;Reuse me!&lt;/code&gt;? Did you notice the key word in there?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reuse&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;If you want more reuse, you have to make it happen&quot;&gt;&lt;/span&gt; When we build modules (functions, objects, whatever) with less knowledge of their surroundings, which depend less on their context, then we naturally build modules more fit for reuse. &lt;strong&gt;No more excuses&lt;/strong&gt;. If you want more reuse, you have to make it happen, and building modules with &lt;strong&gt;context independence&lt;/strong&gt; in mind achieves that aim. We got there by &lt;strong&gt;noticing indirection without abstraction&lt;/strong&gt;, then &lt;strong&gt;inverting the dependency&lt;/strong&gt; (which happened to remove a mock object), then &lt;strong&gt;spotting duplication&lt;/strong&gt;, then extracting that duplication into a &lt;strong&gt;context-independent, reusable module&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We did that&lt;/em&gt;. No magic. “Objects” didn’t even matter here. We could have done the same thing in Haskell with functions. (Remember: a one-method interface and a lambda expression are functionally equivalent.)&lt;/p&gt;
&lt;p&gt;So please stop telling me that &lt;em&gt;object-oriented programming hasn’t fulfilled its promise of increasing code reuse&lt;/em&gt;. &lt;strong&gt;Programmers haven’t taken advantage of their opportunities to extract more-reusable code.&lt;/strong&gt; We don’t have to anticipate all our future needs at once; we can instead notice them as they start to happen, and then extract them when they might help. Some senior programmers call this “over-engineering”, but I see it as engineering just enough and just in time. Extracting frameworks from real production use amounts to doing the same thing in retrospect and in bigger batches as I’ve done here, incrementally, and just in time.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Write code more independent of its context. I find this code easier to test, easier to understand, easier to maintain, more stable, and easier to reuse.
&lt;/p&gt;
&lt;p&gt;Try it!&lt;/p&gt;
&lt;h2 id=&quot;one-more-thing&quot;&gt;One More Thing…&lt;/h2&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;The code doesn’t want a clock; it wants a stream of timestamps.&quot;&gt;&lt;/span&gt; If you just don’t like passing &lt;code&gt;instant&lt;/code&gt; as a parameter here, and prefer something more flexible, then I’d like to suggest an alternative to the &lt;code&gt;Clock&lt;/code&gt; protocol. &lt;code&gt;Clock&lt;/code&gt; feels like a leaky abstraction: although it provides some flexibility in the implementation details, its name reflects an unnecessary assumption about what matters to the code. The code doesn’t want a clock; it wants a stream of timestamps. So give it a stream of timestamps. You could pass an &lt;code&gt;InfiniteIterator&lt;/code&gt; of &lt;code&gt;Timestamp&lt;/code&gt; objects (or whatever you call them in your programming language of choice). &lt;em&gt;This&lt;/em&gt; represents a true abstraction, because it says, “My code needs some timestamps. I don’t know how many it needs and I don’t even care what they represent. My code just needs an endless stream of timestamps.”
&lt;/p&gt;
&lt;p&gt;A frozen clock? That’s just an endless stream of the same timestamp over and over again. A system clock? That’s just an endless stream of calls to &lt;code&gt;Date()&lt;/code&gt;. Tempted to use TimeCop to control the system clock? No need. Just provide an endless stream of whatever timestamps you need. And it all just works like an iterator.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;That’s&lt;/em&gt; abstraction with power.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Martin Fowler, &lt;a href=&quot;https://link.jbrains.ca/19QhAba&quot;&gt;“Transaction Script”&lt;/a&gt;. I often implement my controllers as Transaction Scripts, then as I notice duplication, I start to separate application logic from business logic, moving the application logic up the call stack into “filters” and moving the business logic down the call stack into a Domain Model.&lt;/p&gt;
&lt;p&gt;Martin Fowler, &lt;a href=&quot;https://link.jbrains.ca/TEkD2M&quot;&gt;&lt;em&gt;Patterns of Enterprise Application Architecture&lt;/em&gt;&lt;/a&gt;. A catalog of fundamental patterns in enterprise applications that you likely take for granted by now.&lt;/p&gt;
&lt;p&gt;J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/vN1IiF&quot;&gt;“Injecting Testability Into Your Designs”&lt;/a&gt;. An older article in which I describe a simple example of injecting dependencies new to the concept.&lt;/p&gt;
&lt;p&gt;Michael Feathers, &lt;a href=&quot;https://link.jbrains.ca/1bZXmRc&quot;&gt;&lt;em&gt;Working Effectively with Legacy Code&lt;/em&gt;&lt;/a&gt;. This remains the standard reference for maintaining and living with legacy code.&lt;/p&gt;
&lt;h2 id=&quot;reactions&quot;&gt;Reactions&lt;/h2&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
&lt;p&gt;
Mocks in tests are good, but even better is thinking about what you are trying to accomplish &lt;a href=&quot;https://t.co/RFSF8rpabj&quot;&gt;https://t.co/RFSF8rpabj&lt;/a&gt; /via &lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;&lt;/a&gt;
&lt;/p&gt;
— Chris Hartjes (&lt;span class=&quot;citation&quot; data-cites=&quot;grmpyprogrammer&quot;&gt;@grmpyprogrammer&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/grmpyprogrammer/statuses/404263296083062784&quot;&gt;November 23, 2013&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;If you feel open to learning more about this point, please take a few minutes to read &lt;a href=&quot;/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;“The Eternal Struggle Between the Business and Programmers”&lt;/a&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I have learned to pay attention to my intuition as a software designer, but mostly because &lt;a href=&quot;https://bit.ly/gmeMhh&quot;&gt;I’ve developed that intuition through over a decade of constant, careful practice&lt;/a&gt;.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I learned the term &lt;em&gt;seam&lt;/em&gt; from Michael Feathers’ work on legacy code. A seam provides a place to plug alternative implementations of functions that initially make testing more convenient, but almost always end up improving the design of the system, too.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;We call an operation &lt;em&gt;referentially transparent&lt;/em&gt; if it evaluates to the same value every time. Functionally-minded programmers make a big deal out of this for good reason, as it contributes to repeatability.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn5&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;My good friend Michael Bolton defines “bug” as “something that bugs someone” and “issue” as “something that threatens the value of the system”.&lt;a href=&quot;#fnref5&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn6&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;This illustrates why some people pompously label dependency injection as an overblown consultant-driven marketing phrase. “Real programmers just pass parameters”, they say. Indeed, but I find some value in differentiating passing values to a function and passing collaborating services to a service. I pass values, but I inject collaborators. I don’t see the problem.&lt;a href=&quot;#fnref6&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sat, 23 Nov 2013 07:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/beyond-mock-objects</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/beyond-mock-objects</guid>
        
        
        <category>Test Doubles</category>
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Losing time to Faraday</title>
        <description>&lt;p&gt;I just wanted an HTTP client.&lt;/p&gt;
&lt;p&gt;I asked my Twitter community which HTTP client to use. Certainly not &lt;a href=&quot;https://github.com/jnunemaker/httparty&quot;&gt;HTTParty&lt;/a&gt;, because cool people don’t use &lt;a href=&quot;https://github.com/jnunemaker/httparty&quot;&gt;HTTParty&lt;/a&gt; anymore. One takes these risks when one falls out of the loop with the latest and greatest tools.&lt;/p&gt;
&lt;p&gt;“Use &lt;a href=&quot;https://github.com/lostisland/faraday&quot;&gt;Faraday&lt;/a&gt;”, they said. “It’s the best”, they said.&lt;/p&gt;
&lt;p&gt;Everything went fine until I needed to follow a redirect. What happened from that point forward could form the basis of a solid one-act play. I’ll spare you the horror and send you directly to the punch line.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;connection.adapter Faraday.default_adapter&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- more --&gt;
&lt;h2 id=&quot;when-is-a-default-not-really-a-default&quot;&gt;When Is A Default Not Really A Default?&lt;/h2&gt;
&lt;p&gt;When you use middleware with Faraday. Specifically when you use &lt;code&gt;FaradayMiddleware::FollowRedirects&lt;/code&gt; to follow redirects with Faraday.&lt;/p&gt;
&lt;p&gt;I tried to read the documentation. Honestly. I read &lt;a href=&quot;https://stackoverflow.com/questions/13258068/work-around-rubys-broken-uri-parse-follow-redirects&quot;&gt;Stack Overflow&lt;/a&gt;. I read the &lt;a href=&quot;https://github.com/lostisland/faraday_middleware/wiki&quot;&gt;Faraday Middleware wiki&lt;/a&gt;. I even read the &lt;a href=&quot;https://github.com/lostisland/faraday_middleware/blob/master/lib/faraday_middleware/response/follow_redirects.rb&quot;&gt;source&lt;/a&gt;. Nothing seemed to warn me about this “default adapter” business, and given the name “default”, shouldn’t it—you know—be the default?!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember: &lt;a href=&quot;https://link.jbrains.ca/qVNty9&quot;&gt;ask why, but never answer&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I looked through &lt;a href=&quot;https://github.com/lostisland/faraday_middleware/issues&quot;&gt;Faraday Middleware’s issues&lt;/a&gt; and found evidence that other people had successfully followed redirects with &lt;code&gt;FaradayMiddleware::FollowRedirects&lt;/code&gt;, and so I concluded that I’d done something wrong. I looked for any issue that related to redirects for a clue. I ended up reading &lt;a href=&quot;https://github.com/lostisland/faraday_middleware/issues/75&quot;&gt;an issue&lt;/a&gt; that suggested the possibility of following redirects depending on more details in the original request: follow redirects for this path info, but not that path info, for example.&lt;/p&gt;
&lt;p&gt;Something caught my eye.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
Consider the following code slightly adapted from the readme:
&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;connection = Faraday.new &amp;#39;https://example.com/api&amp;#39; do |conn|
  conn.use FaradayMiddleware::FollowRedirects, limit: 5
  conn.adapter Faraday.default_adapter
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Every request will follow redirects based on the configuration above.
&lt;/p&gt;
&lt;p style=&quot;text-align: right&quot;&gt;
–&lt;a href=&quot;https://github.com/Zorbash&quot;&gt;Dimitrios Zorbas&lt;/a&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;What the hell is this default adapter business?!&lt;/em&gt; I wondered.&lt;/p&gt;
&lt;p&gt;Then I tried it.&lt;/p&gt;
&lt;p&gt;Then it worked.&lt;/p&gt;
&lt;p&gt;Then I tweeted something.&lt;/p&gt;
&lt;p&gt;Then my wife found some calming Dylan Moran comedy&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; and I felt better.&lt;/p&gt;
&lt;p&gt;Of course, &lt;em&gt;now that I know what to look for&lt;/em&gt;, I find &lt;a href=&quot;https://github.com/lostisland/faraday_middleware/issues/32&quot;&gt;the exact issue that I’ve just run into&lt;/a&gt;—and it’s &lt;strong&gt;TWO YEARS OLD&lt;/strong&gt; as of the time I write these words.&lt;/p&gt;
&lt;p&gt;In that issue, &lt;a href=&quot;https://github.com/mislav&quot;&gt;Mislav Marohnić&lt;/a&gt; helpfully points the problem out and suggests following an issue that no longer exists to receive notification when this curious behavior changes. Fortunately, I could easily track down the issue he &lt;em&gt;means&lt;/em&gt;, as the project has since moved. He means &lt;a href=&quot;https://github.com/lostisland/faraday/issues/121&quot;&gt;this issue&lt;/a&gt;. I’ve started following it, and now so can you, in case you want to know when you can safely ignore the dreaded &lt;code&gt;default_adapter&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what-does-this-all-mean&quot;&gt;What Does This All Mean?!&lt;/h2&gt;
&lt;p&gt;It means that if you have this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def http_get(base, uri)
  Faraday.get(base + uri)
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and you want to refactor it to add middleware, &lt;strong&gt;you absolutely positively must write this&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def http_get(base, uri)
  Faraday.new(base) { | connection |
    # IMPORTANT Without this line, nothing will happen.
    connection.adapter Faraday.default_adapter
  }.get(uri)
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you forget to specify the &lt;code&gt;adapter&lt;/code&gt;, then you have not refactored. I hope this helps.&lt;/p&gt;
&lt;h2 id=&quot;but-wait-theres-more&quot;&gt;But Wait! There’s More!&lt;/h2&gt;
&lt;p&gt;I really loved &lt;a href=&quot;https://link.jbrains.ca/WNg8Se&quot;&gt;&lt;em&gt;The Pragmatic Programmer&lt;/em&gt;&lt;/a&gt;, and will probably always remember its section on “programming by coincidence” or, as I like to call it, &lt;em&gt;programming by accident&lt;/em&gt;. One brand of programming by accident involves moving statements around until they work. This relates to &lt;em&gt;temporal coupling&lt;/em&gt;, the extent to which statements depend not just on each other, but on the sequence in which they occur. Some temporal coupling makes perfect sense:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;list = []
list &amp;lt;&amp;lt; &amp;quot;hello&amp;quot;
list.empty? =&amp;gt; false&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rearrange these statements and they say something fundamentally different. This temporal coupling seems quite reasonable to me.&lt;/p&gt;
&lt;p&gt;Accidental&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; temporal coupling, however, creates problems for everyone, except possibly the programmer who created the accidental temporal coupling. &lt;em&gt;Of course&lt;/em&gt;, I had to find out whether this code exhibits accidental temporal coupling. It does.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def http_get(base, uri)
  Faraday.new(base) { | connection |
    # IMPORTANT Without this line AT THE END OF THIS BLOCK, nothing will happen.
    connection.adapter Faraday.default_adapter
  }.get(uri)
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It behooves me, the programmer, to introduce this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def faraday_with_default_adapter(base, &amp;amp;block)
  Faraday.new(base) { | connection |
    yield connection

    # IMPORTANT Without this line, nothing will happen.
    connection.adapter Faraday.default_adapter
  }
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which I can use like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def http_get(base, uri)
  faraday_with_default_adapter(base) { | connection |
    connection.use FaradayMiddleware::FollowRedirects, limit: 1
  }.get(uri)
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thus I program &lt;em&gt;deliberately&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It behooves me more, even, to contribute this back to &lt;a href=&quot;https://github.com/lostisland/faraday&quot;&gt;Faraday&lt;/a&gt;. I’m tired. I’ll do it later.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;You don’t know Dylan Moran?! &lt;a href=&quot;https://www.youtube.com/watch?v=wDIiPIJmXcE&quot;&gt;Start here&lt;/a&gt;.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;As in Fred Brooks and his distinction between essential complication and accidental complication in his classic essay, “No Silver Bullet”. Read more about this distinction in &lt;a href=&quot;/permalink/the-eternal-struggle-between-business-and-programmers&quot;&gt;“The Eternal Struggle Between Business and Programmers”&lt;/a&gt;.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Sun, 17 Nov 2013 14:40:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/losing-time-to-faraday</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/losing-time-to-faraday</guid>
        
        
      </item>
    
      <item>
        <title>The Eternal Struggle Between Business and Programmers</title>
        <description>&lt;p&gt;At Øredev 2013, I asked managers to tell me what makes their job difficult. I spoke to one manager who told me that they face immense pressure on two fronts: from the board of directors to deliver more features more often and from the programmers to give them more time to refactor. I’ve heard dozens of stories like these over the years and I’ve found a trick that helps. It doesn’t &lt;em&gt;resolve&lt;/em&gt; the problem, but it helps take a significant step in the direction of a resolution.&lt;/p&gt;
&lt;p&gt;Warning. You almost certainly have more to deal with in your exact situation than this advice can cover. You might need some more direct help. I can offer that to you, but for now, read on.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;I call it the &lt;em&gt;eternal struggle between the Business and Programmers&lt;/em&gt;. Specifically programmers, because I almost always hear the specific complaint coming from them. It goes like this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Business: More features! Now!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Programmers: More refactoring! Now!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It usually involves more colorful language, more intense emotions, and repeats a few times, but it boils down to this. I notice a few things about this particular exchange.&lt;/p&gt;
&lt;p&gt;First, the Business can easily justify their position: they need profit, and profit comes from sales, and sales come from features, and features come from, among other people, the Programmers. Without more profit, nobody keeps a job.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; Clearly, the Business has this one right.&lt;/p&gt;
&lt;p&gt;Next, the Programmers can easily justify their position: they need to deliver more features, and they can’t deliver features if they don’t understand the code, and almost nobody writes code clearly the first time, so the Programmers need to edit their work, and they call that editing “refactoring”. Without refactoring, features don’t flow, the Business has nothing to sell, we can’t generate profit, and nobody keeps a job. Clearly, the Programmers have this one right.&lt;/p&gt;
&lt;p&gt;Unfortunately, the Business only sees that the Programmers used to deliver features more quickly, and now they want to slow down. This creates obvious tension. This tension slowly pervades every aspect of the relationship between the Business and the Programmers. It obscures something important. I’ll come back to that.&lt;/p&gt;
&lt;p class=&quot;aside&quot;&gt;
Somehow everyone has ignored that the Programmers are slowing down &lt;em&gt;anyway&lt;/em&gt;, because the code gradually forces them to slow down. Interesting.
&lt;/p&gt;
&lt;p&gt;So the Business needs features to sell, but the Programmers want to slow down. The Business needs to feed a market that expects more features sooner, but the Programmers need to feed a design that demands cleanliness as a condition for adding new features as a steady pace. Thus, the eternal struggle, because &lt;strong&gt;it has always been thus&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;help-us-help-you&quot;&gt;Help Us Help You!&lt;/h2&gt;
&lt;p&gt;The Programmers plead: “If only you’d let us refactor! We have a sick design; it actively prevents us from adding features sensibly. It encourages us to do the wrong things. It encourages us to duplicate code, which makes mistakes seem inevitable. It has code that nobody understands any more, and so when we have to change it, we need weeks to read, to research, to gain confidence that changing it won’t anger our existing customers. If you’d let us refactor, then we could spot design improvements that would unblock new features, that could reduce the cost of new features by 20%, 30%, 40%, and more! Why don’t you let us refactor?!” They appear to have a point.&lt;/p&gt;
&lt;p&gt;The Business pleads: “If only you’d stop with this refactoring nonsense! The economy has to grow. We have to grow. The board of directors yells at the vice presidents, who yell at the third-line managers, who yell at the second-line managers, who yell at us. More features! More features! They only want more features! Not only can they not afford for you Programmers to slow down, but they need you to speed up! &lt;em&gt;I&lt;/em&gt; need you to speed up! What do you go faster?!” I don’t envy their situation.&lt;/p&gt;
&lt;h2 id=&quot;the-central-conflict&quot;&gt;The Central Conflict&lt;/h2&gt;
&lt;p&gt;If you’re a Programmer, then imagine yourself in the position of the Business. The Business relies completely on Programmers (among other people) for its survival. I imagine the Business finds this imbalance uncomfortable, even threatening. Without the Programmers, the Business has nothing to sell. Worse, at the source of this tension we find a haphazard, slow stream of half-working, not-quite-what-we-wanted features. It doesn’t matter that the Programmers can easily justify their behavior, because the Market doesn’t like the results, and as soon as the Market has an alternative, it disappears, and nobody keeps a job.&lt;/p&gt;
&lt;p&gt;What can we do?&lt;/p&gt;
&lt;p class=&quot;aside&quot;&gt;
I have to admit that the programmer in me loves that a cyclic dependency lies at the center of this conflict.
&lt;/p&gt;
&lt;h2 id=&quot;the-phrase-that-pays&quot;&gt;The Phrase That Pays&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Refactoring reduces the volatility in the marginal cost of features!&lt;/strong&gt; It smooths out the design, distributing the problems more evenly. It helps the Programmers make many small easy-to-clean-when-needed messes, rather than several small-to-large we-have-to-stop-the-line-to-go-any-further messes. It also helps the Programmers identify game-changing structural improvements that they might not otherwise see—the kind that reduce the cost of future features by 20%, 30%, 40% and more. Refactoring even helps eliminate many classes of annoyingly-costly mistakes. (You might call them “bugs”.) &lt;strong&gt;As certainty in the cost of features goes up, the overall cost of features tends to go down&lt;/strong&gt;. This short talk describes how refactoring and the cost of features relate to each other:&lt;/p&gt;
&lt;figure class=&quot;body-text-block&quot;&gt;
&lt;div class=&quot;embedded-video-container&quot;&gt;
&lt;iframe class=&quot;embedded-video&quot; src=&quot;https://www.youtube.com/embed/WSes_PexXcA?rel=0&quot; frameborder=&quot;0&quot; allow=&quot;encrypted-media&quot; allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=WSes_PexXcA&quot;&gt;7 minutes, 26 seconds, and the Fundamental Theorem of Agile Software Development&lt;/a&gt; from &lt;a href=&quot;https://www.jbrains.ca&quot;&gt;J. B. Rainsberger&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// Fucking absurd hack, because I don&apos;t know how to make
// Node.js modules import &quot;plain&quot; (non-Node) Javascript
// source files
var module = { exports: [] };
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/javascript/toggle.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var sketchnoteDisplayPeer = { displayState: &quot;none&quot; };
var transcriptDisplayPeer = { displayState: &quot;none&quot; };

function toggleSketchnoteFor7m26s(document) {
  toggleDisplayFor(document.querySelector(&quot;#sketchnote_7m26s&quot;), sketchnoteDisplayPeer);
}

function toggleTranscriptFor7m26s(document) {
  toggleDisplayFor(document.querySelector(&quot;#transcript_7m26s&quot;), transcriptDisplayPeer);
}
&lt;/script&gt;
&lt;p&gt;(If you prefer to read a transcript of this talk, &lt;a href=&quot;javascript:toggleTranscriptFor7m26s(document)&quot;&gt;click here&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;(If you’d like to see a sketchnote of this talk, &lt;a href=&quot;javascript:toggleSketchnoteFor7m26s(document)&quot;&gt;click here&lt;/a&gt;.)&lt;/p&gt;
&lt;div id=&quot;transcript_7m26s&quot; style=&quot;display: none&quot;&gt;
&lt;pre&gt;
Seven minutes 26 seconds. 
Fred Brooks, Mythical Man-Month, No Silver
Bullet. How many of you read it? 
Not enough. 

Accidental complication and essential complication. 

Not complexity, because complexity implies emergence. And
I&apos;m just talking about complication. No such thing as an
order of magnitude improvement in performance in part
because of accidental complication. 

Essential complication because the problem is hard. The
problem is hard so the system is complicated. You want to
audit a tax return? Have you read the tax code in Canada?
It&apos;s this thick. Essential complication.

Accidental complication... we&apos;re not so good at our jobs.

Accidental complication because we cut corners, we feel
pressure, we don&apos;t have to worry about it this time, we
don&apos;t have to re-factor so much, we have to get it out the
door. 

Accidental complication. Essential complication.

The cost of a feature is a function of the cost coming from
the essential complication because the problem is hard and
the cost of accidental complication because we suck at our
jobs. Roughly speaking we can add these things together. How
do you estimate, if you estimate? 

Don&apos;t estimate. 

But if you estimate how do you estimate? This thing is kind
of hard. This thing is kind of the same kind of hard. This
thing took two weeks. This thing, two weeks.

Here&apos;s the problem: Friday afternoon meeting, &quot;Don&apos;t worry,
boss. Three days.&quot; Monday morning, &quot;Oh shit. Make that three
months.&quot; Why? 

Accidental complication. 

Most people most of the time the cost of a feature is 
dominated, 
dominated, 
dominated 
by the cost from accidental complication. That means that
the cost of your feature has almost nothing to do with how
hard it is and almost everything to do with how much your
design sucks.

What can we do? Test driven development to the rescue. (Of
course he was going to say that.) 

Well, what the hell do you mean? 

Test driven development step one: think. (Everyone forgets
that step.) Step two: write a test. Step three: stand back
and ask, &quot;How much does this test suck? Is it too long? Does
it have irrelevant details? Can I make the test smaller,
simpler?&quot; Congratulations, you&apos;re removing accidental
complication. 

Step three: run the test and watch it fail. You&apos;d be
surprised how often it doesn&apos;t actually fail. Why doesn&apos;t it
fail? Well, I&apos;m running the wrong tests. No, that&apos;s not the
problem. I forgot to check something. No, I&apos;m responsible. I
write the assertion first. That&apos;s not the problem. I wrote
too much code last time and it already passes the test. I
should stop doing that.

Accidental complication.

Step four: write just enough code to make it pass. 
Just enough code to make it pass. 
Just enough code to make it pass. 
Not the line of code you know you have to write. Just enough
code to make it pass. Return 12. If input is 7, return 12,
else return 13. Weird. Good enough. If every product in our 
shop is either 12 or 13 dollars, we&apos;re done.

Another if statement: now it&apos;s a lookup table. Let&apos;s move
the lookup table here, then here, then here. Now we have
MVC. Accidental complication. We have to figure out how to
remove it. And so after we write just enough code to make
the test pass the next thing we do is we clean the kitchen.
We refactor a bit now. We have made a little mess to add
some behavior and now we smooth that little mess out.
Because if we don&apos;t clean the kitchen then we have to clean
the garage. Cleaning the garage is a bigger job. We always
put it off. We hate it when we have to do it. The only time
we clean the garage is when there&apos;s no more room for the
car. Clean the kitchen.

Cleaning the kitchen, reducing accidental complication.

So far: think, write the test, watch it fail, write just
enough code to make the test pass...

(give your computer caffeine so that you can see the timer,
mistype your password because you&apos;re trying to go too
quickly.)

Reduce accidental complication.

So write a test, limit the amount of code you&apos;re trying to
write at once. Reduce accidental complication. 

Ask yourself, &quot;Does the test suck?&quot; Remove accidental
complication. 

Finally, make the test pass. Refactor, clean the kitchen.
Reduce the accidental complication that gets in because you
didn&apos;t do a good job of avoiding it in the first place.
You&apos;re getting better. 

Every few minutes. 
Every few minutes. 
Every few minutes.

At the top of the circle, avoid accidental complication. At
the bottom of the circle, squeeze out the accidental
complication that got in while you weren&apos;t looking. Why?
Because if the cost of a feature is the cost of the
essential complication plus the cost of the accidental
complication and if we compare estimates based on essential
complication - how hard is the problem if it&apos;s roughly as
hard as that thing that took two weeks it should take two
weeks.

But if the cost from accidental complication dominates the
cost of the feature, then you arrive at the fundamental
theorem of agile software development. 

Not enough of you are leaning in. 

The fundamental theorem of agile software development says
this: If you want to estimate little things you have to
refactor because refactoring is how you reduce accidental
complication and only by driving accidental complication
down as far as you possibly can will your relative estimates
have any meaning.

Here&apos;s the proof: f(essential complication, accidental
complication) = g(essential complication) + h(accidental
complication). f is supposed to be proportional to g. 

But you have h. 

h either has to be a perfect multiple of g (how many times
have you worked in a code base where the shit was uniformly
distributed throughout the code?) or h has to be - say it
with me - zero. Because if h is anything bigger than zero
and h is not a multiple of g, then f will not be
proportional to g and 
your 
relative 
estimates 
will 
be 
to-
tal 
bull-
shit.

Therefore, if you&apos;re going to estimate, you&apos;d better
refactor which means Scrum cannot work without XP. This has
been seven minutes and 26 seconds.

Questions?

&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&quot;sketchnote_7m26s&quot; style=&quot;display: none&quot;&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/7m26s-sketchnote-DerekGraham.jpg&quot; alt=&quot;A sketchnote from Derek Graham&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;A sketchnote from &lt;a href=&quot;//twitter.com/deejaygraham&quot;&gt;Derek Graham&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 id=&quot;why-the-problem-is-a-problem&quot;&gt;Why “The Problem” Is A Problem&lt;/h2&gt;
&lt;p&gt;Over time, the Business has coerced the Programmers into stealing future capacity by pressuring them to not cultivate a healthy design. They have probably done this for a long time. Don’t blame the Business for this: the Industry has largely taught them to do it. On the other hand, the Programmers haven’t used a particularly meaningful defence: they’ve appealed to arguments based on some abstraction notion of craftsmanship. Some Businesses want to buy craftsmanship; others need features &lt;em&gt;now&lt;/em&gt;!&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, we can realize something significant: &lt;strong&gt;The Business and the Programmers want the same thing&lt;/strong&gt;. They want the same thing: to deliver a more predictable stream of important features that will make the market happy—or, at least, knowing the fickle market, that will risk disappointing them the least.&lt;/p&gt;
&lt;p&gt;This. Is. Glorious.&lt;/p&gt;
&lt;h2 id=&quot;mending-the-rift&quot;&gt;Mending The Rift&lt;/h2&gt;
&lt;p&gt;The Business and the Programmers need to agree on two things, &lt;strong&gt;each conceding a key point to the other&lt;/strong&gt;. The Business needs to agree that the Programmers have been going &lt;strong&gt;more quickly than they really can&lt;/strong&gt;, that they cannot sustain this pace, and that trying to do it leads to disaster. We are driving in a car accelerating towards a brick wall. The Programmers need to agree that the Business has a legitimate need to deliver more features, that everyone’s livelihood depends on this, and that &lt;strong&gt;“it’s the Business’ job” to ask for more than the Programmers can ever deliver&lt;/strong&gt;. The market compels them to do this—if it doesn’t, then where does the revenue come from? In this equation, the Programmers have the responsibility to do whatever they can to maximize their &lt;strong&gt;ongoing&lt;/strong&gt; delivery speed, and that includes regular, aggressive refactoring.&lt;/p&gt;
&lt;p&gt;Finally, both the Business and the Programmers have to agree that they have wasted too much time arguing about this and need to move forward. They want the same thing! They can have it!&lt;/p&gt;
&lt;p&gt;Thus, I propose a kind of detente. The Business agrees to remember that the Programmers always try their best to go at a fast-but-sustainable pace. The Programmers agree to remember that the Business also feels threatening pressure to perform, and that they don’t feel comfortable relying so much on the Programmers for their success. Each group needs the other desperately, and together they all want the same thing.&lt;/p&gt;
&lt;p&gt;…and let’s not forget the Testers and Operations and other departments. If we listen to each other, we’ll realize that we all want the same things, and together, we can make things so much better.&lt;/p&gt;
&lt;p&gt;Good programmers with great habits will help your project succeed, but even the greatest programmers with the greatest habits can’t guarantee the results you need. You need help with your tough questions. You need somewhere to go to ask whether you’re on the right track, making the right decision, solving the right problem. It’s hard to tell the good advisers from the bad. If you like what I have to say, then you’d probably enjoy having me on your team.&lt;/p&gt;
&lt;p&gt;You could hire me for on-site coaching, but that’s expensive and you might not feel ready to make that kind of investment. You might not even need that much of me! Now you can get the advice you need from a trusted source at a very reasonable price. Visit &lt;a href=&quot;http://experience.jbrains.ca&quot;&gt;The jbrains Experience&lt;/a&gt; and get started for less than it costs to get your team together for a 30-minute meeting.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I’ll leave aside the question of “enough” profit for another time.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Let me be very, very clear: I support the software craftsmanship movement, because it takes a pragmatic view of craftsmanship. Just because they call it “craft” doesn’t give them licence to take all the time in the world, and a competent, caring software craftsperson will not do this. Even so, a typical Business reaction to the notion of “craft” is “artisan”, a Greek word meaning “slow and expensive”.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Mon, 11 Nov 2013 01:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-eternal-struggle-between-business-and-programmers</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-eternal-struggle-between-business-and-programmers</guid>
        
        
        <category>Simple Design</category>
        
        <category>Surviving Legacy Code</category>
        
        <category>Not Just Coding</category>
        
      </item>
    
      <item>
        <title>The Pain of Implicit Dependencies</title>
        <description>&lt;p&gt;Legacy code imposes an unbounded, inexact tax on the cost of all future features. This explains why I run events like Legacy Code Retreat, build training courses like &lt;a href=&quot;https://surviving-legacy-code.jbrains.ca&quot;&gt;Surviving Legacy Code&lt;/a&gt;, and write in general about improving the design of software systems. This further explains why I’m willing to accept the risk of people labeling me as an “over-engineerer”. &lt;strong&gt;What they label “over-engineering”, I consider &lt;em&gt;managing risk&lt;/em&gt;&lt;/strong&gt;. As part of managing risk, I like to test-drive changes to legacy code, and implicit dependencies almost always get in the way of starting. I’m going through this right now, working with Octopress, the blogging software that I use here. (Update in 2017: I have since switched from Octopress to Jekyll.)&lt;/p&gt;
&lt;h2 id=&quot;the-task&quot;&gt;The Task&lt;/h2&gt;
&lt;p&gt;Some time ago, gists started looking bad on this blog. I apologize for that. Gists looked (or still look, depending on when you read this) like this:&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/PainOfImplicitDependencies/example-gist-formatting-problem.png&quot; alt=&quot;Gists behaving badly&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Gists behaving badly&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;After a few hours of looking around for solutions, I decided that Github’s gist stylesheet had caused me the most misery, so I decided to sidestep it, which meant no longer embedded the gists using Javascript. This coincidentally solved some other problems, so I went with it. After some more time exploring &lt;em&gt;how&lt;/em&gt; to do this, I settled on a simple-sounding approach: create a new Octopress tag that downloads the raw gist and displays it using the &lt;code&gt;codeblock&lt;/code&gt; tag, which Octopress already ships.&lt;/p&gt;
&lt;p class=&quot;aside&quot;&gt;
Update 2017: Now I just use fenced code blocks in place of the &lt;code&gt;codeblock&lt;/code&gt; Liquid tag, but the points of this article still stand.
&lt;/p&gt;
&lt;p&gt;How hard could this possibly be?&lt;/p&gt;
&lt;h2 id=&quot;heres-how-hard-this-could-possibly-be&quot;&gt;Here’s How Hard This Could Possibly Be&lt;/h2&gt;
&lt;p&gt;In order to test-drive my changes, I need to move as quickly as possible outside Octopress’s runtime environment, because otherwise my tests will forever remain big, brittle, and a ticking time bomb. I need to understand more about the contract of &lt;code&gt;CodeBlock&lt;/code&gt; so that I can invoke it correctly from my custom &lt;code&gt;Liquid::Block&lt;/code&gt; implementation. In the process of running some end-to-end tests—these help me discover the boundaries between “my stuff” and “their stuff”—I find what looks like a mistake in &lt;code&gt;CodeBlock&lt;/code&gt;: when I specify only the URL for a code block (not a title nor link text), &lt;code&gt;CodeBlock&lt;/code&gt; interprets the URL as a filename and tries to extract a file type for syntax highlighting, and so it thinks that the link’s top-level domain is the type of the code block. Oops. Naturally I want to verify that this class doesn’t &lt;em&gt;intend&lt;/em&gt; to behave this way, and so I try writing some tests, since that will force me to think about this issue more deeply and, if I have things wrong, notice my own mistake.&lt;/p&gt;
&lt;h3 id=&quot;is-this-thing-on&quot;&gt;Is This Thing On?&lt;/h3&gt;
&lt;p&gt;I try writing a dead-simple test that instantiates the class I want to check. I’ve learned to get this running before I try to do anything more complicated, because legacy environments often surprise me.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;require &amp;quot;rspec&amp;quot;

describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;Am I requiring everything correctly?&amp;quot; do
    Jekyll::CodeBlock.new
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Predictably, this fails with &lt;code&gt;uninitialized constant Jekyll&lt;/code&gt;. Of course, I need to &lt;code&gt;require&lt;/code&gt; the production code I want to check, so I do that.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;require &amp;quot;rspec&amp;quot;
require &amp;quot;./plugins/code_block&amp;quot;

describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;Am I requiring everything correctly?&amp;quot; do
    Jekyll::CodeBlock.new
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hate the relative &lt;code&gt;require&lt;/code&gt; path, because that encodes knowledge of where I’ve put my &lt;code&gt;spec&lt;/code&gt; directory, and &lt;a href=&quot;/permalink/relative-include-paths-and-the-slow-certain-march-towards-legacy-code&quot;&gt;&lt;em&gt;that creates context dependence&lt;/em&gt;&lt;/a&gt;. Quickly, I change the &lt;code&gt;require&lt;/code&gt; path and when I run my specs, I run them with &lt;code&gt;-I .&lt;/code&gt; so that ruby finds the production code.&lt;/p&gt;
&lt;p class=&quot;highlight&quot;&gt;
I moved the decision up the call stack! Instead of the &lt;code&gt;ruby&lt;/code&gt; code saying “look for &lt;code&gt;require&lt;/code&gt; files in the current working directory”, I’ve moved that decision up to its immediate caller: the shell command that launches the &lt;code&gt;ruby&lt;/code&gt; code. This illustrates what I meant in &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle/#move-implementation-choices-up-the-call-stack&quot;&gt;“Move Implementation Choices Up the Call Stack”&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Of course, I don’t want to forget this important detail, and it seems like the kind of thing I will forget easily, so I capture it in a script, which I can eventually take into a &lt;code&gt;rake&lt;/code&gt; task.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;require &amp;quot;rspec&amp;quot;
require &amp;quot;plugins/code_block&amp;quot;

describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;Am I requiring everything correctly?&amp;quot; do
    Jekyll::CodeBlock.new
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;#!/bin/bash

## I don&amp;#39;t know how better to specify &amp;quot;the root of this project&amp;quot;
PLUGIN_PRODUCTION_CODE_ROOT=&amp;quot;.&amp;quot;
bundle exec rspec -I $PLUGIN_PRODUCTION_CODE_ROOT spec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I believe that my tests &lt;code&gt;require&lt;/code&gt; the right things, but when I run them, I see that the legacy environment has thrown me a curveball.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/Users/jbrains/Workspaces/octopress/plugins/raw.rb:22:in `&amp;lt;module:Jekyll&amp;gt;&amp;#39;: uninitialized constant Jekyll::Liquid (NameError)
    from /Users/jbrains/Workspaces/octopress/plugins/raw.rb:21:in `&amp;lt;top (required)&amp;gt;&amp;#39;
    from /Users/jbrains/Workspaces/octopress/plugins/code_block.rb:45:in `require&amp;#39;
    from /Users/jbrains/Workspaces/octopress/plugins/code_block.rb:45:in `&amp;lt;top (required)&amp;gt;&amp;#39;
    from /Users/jbrains/Workspaces/octopress/spec/learn_code_block_spec.rb:2:in `require&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My tests &lt;code&gt;require&lt;/code&gt; files correctly, but the &lt;em&gt;production code&lt;/em&gt; does not. &lt;em&gt;Yet more context dependence&lt;/em&gt;, because &lt;code&gt;CodeBlock&lt;/code&gt; needs &lt;code&gt;Jekyll&lt;/code&gt;, but doesn’t &lt;code&gt;require&lt;/code&gt; it. Now I might simply not know about some standard ruby idiom for requiring files, but my simple, first-principles analysis of the situation tells me that files that &lt;code&gt;require&lt;/code&gt; other files should just &lt;code&gt;require&lt;/code&gt; those files. I suppose I would prefer it if &lt;code&gt;plugins/code_block.rb&lt;/code&gt; could &lt;code&gt;require&lt;/code&gt; only the small parts of &lt;code&gt;Jekyll&lt;/code&gt; that it needs, but at a minimum, it ought not to force every client to &lt;code&gt;require&lt;/code&gt; the parts of &lt;code&gt;Jekyll&lt;/code&gt; that it needs. It ought not even to force clients to &lt;em&gt;know&lt;/em&gt; which parts of &lt;code&gt;Jekyll&lt;/code&gt; it needs. This sounds like a job for &lt;a href=&quot;https://www.twitter.com/raganwald&quot;&gt;Reg&lt;/a&gt;’s article on &lt;a href=&quot;https://link.jbrains.ca/1653RlF&quot;&gt;defactoring&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;pullquote-right&quot; data-pullquote=&quot;when we need flexibility we factor, and when we don’t, we defactor.&quot;&gt;&lt;/span&gt; What about injecting dependencies and moving collaborators up the call stack? Didn’t I make &lt;a href=&quot;/permalink/consequences-of-dependency-inversion-principle&quot;&gt;a big freaking deal&lt;/a&gt; about that recently? Why yes, I did. As Reg points out in his article, when we need flexibility we factor, and when we don’t, we defactor. When I test-drive tiny pieces of a system, I want maximum flexibility in connecting those pieces together, so I factor, which in that case involves moving collaborators up the call stack. When I package those pieces together as a ready-made system for you to use, I introduce something at the root of all my little pieces that puts them together in a cohesive manner that solves a specific problem, which you might interpret as defactoring, but which I interpret as mere politeness: giving you a bicycle, rather than an enterprise-caliber personal locomotion device toolkit. Therefore:
&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
If your code needs something, then either provide it yourself (defactor) or make it clear to me that I need to provide it (factor explicitly). &lt;strong&gt;When we introduce implicit dependencies, we don’t factor, we create legacy code.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;Of course, I don’t want to mess with &lt;code&gt;CodeBlock&lt;/code&gt; yet, because I don’t understand enough about how it works, and I &lt;em&gt;certainly&lt;/em&gt; don’t intend to tell all those Octopress plugin authors that “they’re doing it wrong”, so I &lt;code&gt;require&lt;/code&gt; what I need along with a &lt;code&gt;SMELL&lt;/code&gt; comment to remind me that I don’t want to have to do this.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# SMELL Production code needs Jekyll, but doesn&amp;#39;t require it, so this file has to.
require &amp;quot;jekyll&amp;quot;

require &amp;quot;rspec&amp;quot;
require &amp;quot;plugins/code_block&amp;quot;

describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;Am I requiring everything correctly?&amp;quot; do
    Jekyll::CodeBlock.new
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At least now, when I run my tests, I see a coding error, rather than an environment error.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Failures:

  1) Parsing parameters for codeblock Am I requiring everything correctly?
     Failure/Error: Jekyll::CodeBlock.new
     ArgumentError:
       wrong number of arguments (0 for 3)
     # ./plugins/code_block.rb:54:in `initialize&amp;#39;
     # ./spec/learn_code_block_spec.rb:9:in `new&amp;#39;
     # ./spec/learn_code_block_spec.rb:9:in `block (2 levels) in &amp;lt;top (required)&amp;gt;&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;enough-legacy-environment-now-legacy-code&quot;&gt;Enough Legacy Environment; Now Legacy Code&lt;/h2&gt;
&lt;p&gt;I can now start writing tests for what I truly want to check: what happens when I specify a URL, but neither a title nor link text. Although I normally start my tests with the assertion, when working with legacy code, I prefer to run the action first, because that will probably introduce more hurdles to overcome. Unsurprisingly, that happened this time, too.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# SMELL Production code needs Jekyll, but doesn&amp;#39;t require it, so this file has to.
require &amp;quot;jekyll&amp;quot;

require &amp;quot;rspec&amp;quot;
require &amp;quot;plugins/code_block&amp;quot;

describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  def code_block_with_url(url)
    irrelevant_tokens = []
    Jekyll::CodeBlock.new(&amp;quot;irrelevant tag name&amp;quot;, &amp;quot;https://gist.github.com/1234&amp;quot;, irrelevant_tokens)
  end

  example &amp;quot;only a URL&amp;quot; do
    code_block_with_url(&amp;quot;https://gist.github.com/1234&amp;quot;)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Failures:

  1) Parsing parameters for codeblock only a URL
     Failure/Error: Jekyll::CodeBlock.new(&amp;quot;irrelevant tag name&amp;quot;, &amp;quot;https://gist.github.com/1234&amp;quot;, irrelevant_tokens)
     Liquid::SyntaxError:
       irrelevant tag name tag was never closed
     # ./plugins/code_block.rb:73:in `initialize&amp;#39;
     # ./spec/learn_code_block_spec.rb:10:in `new&amp;#39;
     # ./spec/learn_code_block_spec.rb:10:in `code_block_with_url&amp;#39;
     # ./spec/learn_code_block_spec.rb:14:in `block (2 levels) in &amp;lt;top (required)&amp;gt;&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t care about closing tags; I only care about parsing text. &lt;em&gt;Yet more context dependence.&lt;/em&gt; In this case, &lt;code&gt;CodeBlock&lt;/code&gt;’s constructor invokes &lt;code&gt;super&lt;/code&gt;, which invokes the &lt;code&gt;Liquid&lt;/code&gt; framework. This defeats the purpose of a framework. This particular example typifies two problems: a framework extension point invoking the framework directly and inheriting implementation. I prefer not to do either.&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Framework invokes you; you invoke libraries. Never invoke a framework directly.
&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Inheriting implementation (subclassing) hardwires you to depend on potentially untested and untrusted code, so inherit interface (protocol) instead.
&lt;/p&gt;
&lt;p&gt;How do I escape the annoying context of &lt;code&gt;Liquid&lt;/code&gt; with minimal change to the production code? I use a trick that I teach in &lt;a href=&quot;https://surviving-legacy-code.jbrains.ca&quot;&gt;Surviving Legacy Code&lt;/a&gt;: I extract a pure function that parses the parameters. &lt;strong&gt;I have to do this carefully&lt;/strong&gt;, because I don’t have tests to shield me from my own mistakes. I hate doing this kind of surgery, but I can’t think of a better way to do this. I perform these steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Copy the parsing code to a new function. (&lt;strong&gt;Never cut; always copy, then fix, then delete.&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Add the input parameters that the function needs.&lt;/li&gt;
&lt;li&gt;Return a &lt;code&gt;Hash&lt;/code&gt; containing the values of the fields that the function sets.&lt;/li&gt;
&lt;li&gt;Change the fields to local variables.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This last step stops the function from writing to its surrounding context, but the function still reads from its surrounding context: it uses two constants. I won’t let that stop me from my next step, but I do need to remember to fix that.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;module Jekyll
  class CodeBlock &amp;lt; Liquid::Block
    include HighlightCode
    include TemplateWrapper
    CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/i
    Caption = /(\S[\S\s]*)/

    def initialize(tag_name, markup, tokens)
      @title = nil
      @caption = nil
      @filetype = nil
      @highlight = true
# BEGIN EXTRACTING HERE
      if markup =~ /\s*lang:(\S+)/i
        @filetype = $1
        markup = markup.sub(/\s*lang:(\S+)/i,&amp;#39;&amp;#39;)
      end
      if markup =~ CaptionUrlTitle
        @file = $1
        @caption = &amp;quot;&amp;lt;figcaption&amp;gt;&amp;lt;span&amp;gt;#{$1}&amp;lt;/span&amp;gt;&amp;lt;a href=&amp;#39;#{$2}&amp;#39;&amp;gt;#{$3 || &amp;#39;link&amp;#39;}&amp;lt;/a&amp;gt;&amp;lt;/figcaption&amp;gt;&amp;quot;
      elsif markup =~ Caption
        @file = $1
        @caption = &amp;quot;&amp;lt;figcaption&amp;gt;&amp;lt;span&amp;gt;#{$1}&amp;lt;/span&amp;gt;&amp;lt;/figcaption&amp;gt;\n&amp;quot;
      end
      if @file =~ /\S[\S\s]*\w+\.(\w+)/ &amp;amp;&amp;amp; @filetype.nil?
        @filetype = $1
      end
# END EXTRACTING HERE
      super
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I extracted &lt;code&gt;parse_tag_parameters&lt;/code&gt;, which turns markup into the set of fields that the previous code wrote to.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;module Jekyll
  class CodeBlock &amp;lt; Liquid::CodeBlock
    # unimportant stuff elided
    def self.parse_tag_parameters(markup)
      if markup =~ /\s*lang:(\S+)/i
        filetype = $1
        markup = markup.sub(/\s*lang:(\S+)/i,&amp;#39;&amp;#39;)
      end
      if markup =~ CaptionUrlTitle
        file = $1
        caption = &amp;quot;&amp;lt;figcaption&amp;gt;&amp;lt;span&amp;gt;#{$1}&amp;lt;/span&amp;gt;&amp;lt;a href=&amp;#39;#{$2}&amp;#39;&amp;gt;#{$3 || &amp;#39;link&amp;#39;}&amp;lt;/a&amp;gt;&amp;lt;/figcaption&amp;gt;&amp;quot;
      elsif markup =~ Caption
        file = $1
        caption = &amp;quot;&amp;lt;figcaption&amp;gt;&amp;lt;span&amp;gt;#{$1}&amp;lt;/span&amp;gt;&amp;lt;/figcaption&amp;gt;\n&amp;quot;
      end
      if file =~ /\S[\S\s]*\w+\.(\w+)/ &amp;amp;&amp;amp; filetype.nil?
        filetype = $1
      end
      return {filetype: filetype, file: file, caption: caption}
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have not yet changed the constructor to use this newly-extracted function out of a desire to do this &lt;strong&gt;safely&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now, at least, I can greatly simplify the test.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# SMELL Production code needs Jekyll, but doesn&amp;#39;t require it, so this file has to.
require &amp;quot;jekyll&amp;quot;

require &amp;quot;rspec&amp;quot;
require &amp;quot;plugins/code_block&amp;quot;

describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;only a URL&amp;quot; do
    Jekyll::CodeBlock.parse_tag_parameters(&amp;quot;https://gist.github.com/1234&amp;quot;)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can even run this test and it does nothing. With legacy code, this represents progress.&lt;/p&gt;
&lt;h3 id=&quot;how-about-we-check-something-now&quot;&gt;How about we check something now?&lt;/h3&gt;
&lt;p&gt;Now to the actual mistake—or at least what seems like a mistake. When I don’t provide any clue about the “type” of the code snippet—whether to interpret it as Java code, Ruby code, or something else—then perhaps the &lt;code&gt;filetype&lt;/code&gt; should be &lt;code&gt;nil&lt;/code&gt;. At a minimum, it shouldn’t be what it is now.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;only a URL&amp;quot; do
    results = Jekyll::CodeBlock.parse_tag_parameters(&amp;quot;https://gist.github.com/1234&amp;quot;)
    results[:filetype].should be_nil
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;  1) Parsing parameters for codeblock only a URL
     Failure/Error: results[:filetype].should be_nil
       expected: nil
            got: &amp;quot;com&amp;quot;
     # ./spec/learn_code_block_spec.rb:10:in &amp;#39;block (2 levels) in &amp;lt;top (required)&amp;gt;&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My code snippet certainly doesn’t contain code of type “com”, whatever &lt;em&gt;that&lt;/em&gt; means, so I interpret this as a mistake and change my test accordingly.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;describe &amp;quot;Parsing parameters for codeblock&amp;quot; do
  example &amp;quot;only a URL&amp;quot; do
    results = Jekyll::CodeBlock.parse_tag_parameters(&amp;quot;https://gist.github.com/1234&amp;quot;)
    pending(&amp;quot;Filetype appears to be interpreted incorrectly&amp;quot;) do
      results[:filetype].should be_nil
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I should remove the duplication in &lt;code&gt;CodeBlock&lt;/code&gt; to avoid future mistakes. This involves wiring its constructor, &lt;strong&gt;very carefully&lt;/strong&gt; to the code I’ve just extracted.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;module Jekyll
  class CodeBlock &amp;lt; Liquid::Block
    def initialize(tag_name, markup, tokens)
      @title = nil
      @caption = nil
      @filetype = nil
      @highlight = true

      parsed_tag_parameters = self.class.parse_tag_parameters(markup)
      @filetype = parsed_tag_parameters[:filetype]
      @file = parsed_tag_parameters[:file]
      @caption = parsed_tag_parameters[:caption]

      super
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some rudimentary manual checking convinced me that this change hasn’t broken anything. With legacy code, sometimes we can’t do any better than that, which explains why I go to such pains to avoid writing more of it.&lt;/p&gt;
&lt;p&gt;Of course, now I see some silly-looking duplication in the constructor, so I remove it. I also see some possibly-obsolete code, so I mark it as such. I’ll need to explore more whether I can safely delete that code.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;module Jekyll
  class CodeBlock &amp;lt; Liquid::Block
    def initialize(tag_name, markup, tokens)
      # SMELL This appears to be completely unused.
      @title = nil
      @highlight = true

      parsed_tag_parameters = self.class.parse_tag_parameters(markup)
      @filetype = parsed_tag_parameters[:filetype]
      # SMELL This appears to be completely unused.
      @file = parsed_tag_parameters[:file]
      @caption = parsed_tag_parameters[:caption]

      super
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what-now&quot;&gt;What now?&lt;/h2&gt;
&lt;p&gt;Now I can explore more fully and more safely the behavior of parsing the &lt;code&gt;CodeBlock&lt;/code&gt;’s tag parameters, and I won’t bore you with the details. I can do all this with tests that depend only on the existence of the module &lt;code&gt;Jekyll&lt;/code&gt;, but on none of its behavior. Not perfect, but much better. I don’t yet need to factor out the &lt;code&gt;parse_tag_parameters()&lt;/code&gt; behavior any more, but I feel much more comfortable doing that when the time comes, because I know it will cost me much less than it cost me to get to this point.&lt;/p&gt;
&lt;p&gt;The lesson?&lt;/p&gt;
&lt;p class=&quot;guideline&quot;&gt;
Don’t depend on your clients. If you have to depend on your clients, depend on as little as possible, and remove that dependency as soon as you can.
&lt;/p&gt;
&lt;p&gt;All legacy code started with “I’ll just cut this little corner, and it won’t be so bad….”&lt;/p&gt;
&lt;h2 id=&quot;an-annoying-epilogue&quot;&gt;An annoying epilogue&lt;/h2&gt;
&lt;p&gt;By the way, in the process of exploring how to contribute these changes back to Octopress, I discovered that a new major release is coming and everything will have changed. No good deed goes unpunished.&lt;/p&gt;
&lt;h2 id=&quot;a-less-annyoing-epiepilogue&quot;&gt;A less-annyoing epiepilogue&lt;/h2&gt;
&lt;p&gt;I switched from Octopress to Jekyll. Since Octopress was moving in the direction of “a bunch of plugins for Jekyll”, this move was likely to happen.&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Oct 2013 12:39:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-pain-of-implicit-dependencies</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-pain-of-implicit-dependencies</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Listening to your code does not mean conducting a seance</title>
        <description>&lt;p&gt;I love having tricky conversations on Twitter. I know a lot of you don’t, because you can’t express yourself clearly in 140 characters or less, but I love it for precisely that reason. The constraint makes it easy to voice objections, which makes assumptions visible and encourages us to challenge them. You’d be amazed at the things that people object to – issues that you thought were settled a long time ago, which you take for granted, at least within certain of your social circles.&lt;/p&gt;
&lt;p&gt;This Twitter conversation reminded me of one of my own, long-standing assumptions… the one upon which I based the name of this website.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;https://twitter.com/ecomba&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;ecomba&quot;&gt;@ecomba&lt;/span&gt;&lt;/a&gt; &lt;a href=&quot;https://twitter.com/jbrains&quot;&gt;&lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt;&lt;/a&gt; The more I hear this notion expressed in summary, the harder it is for me to keep liking it.
&lt;/p&gt;
— Tracy Harms (&lt;span class=&quot;citation&quot; data-cites=&quot;kaleidic&quot;&gt;@kaleidic&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/kaleidic/statuses/350066667709140992&quot;&gt;June 27, 2013&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;You owe it to yourself to read the entire conversation, so click on the Tweet’s timestamp and read further. Allow me to summarize: Letting your code tell you where it wants to go does not mean conducting a seance, speaking to the dead.&lt;/p&gt;
&lt;div data-markdown=&quot;1&quot;&gt;
&lt;figure style=&quot;float: right; padding: 0em 0em 1em 1em; margin: 0px&quot;&gt;
&lt;img src=&quot;/images/Original_ouija_board.jpg&quot;&gt;
&lt;figcaption&gt;
This is not in my design toolbox
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In case that conversation link has long-since died, let me state very clearly that when I write code, it might &lt;em&gt;look&lt;/em&gt; like I use a Ouija board, except that I &lt;em&gt;know&lt;/em&gt; that I’m controlling it. I’m looking for signals in my code to indicate design problems, then I decide which problems to address right now, then decide what to do about them. Some signals hit me more strongly than others. Over time I have developed an awareness of and a sensitivity to an ever-growing number of different signals that indicate potential design problems.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I just find it more fun to say that my code tells me where it wants to go. Please don’t interpret this too literally.&lt;/p&gt;
</description>
        <pubDate>Thu, 27 Jun 2013 11:28:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/listening-to-your-code-does-not-mean-conducting-a-seance</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/listening-to-your-code-does-not-mean-conducting-a-seance</guid>
        
        
      </item>
    
      <item>
        <title>Primitive Obsession Obsession</title>
        <description>&lt;p&gt;A Twitter conversation about Primitive Obsession caught my eye today. That conversation began with this tweet:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;
&lt;p&gt;
Re. “primitive obsession,” I say this poker-scoring program wouldn’t be bettered avoiding integers for rank and suit. &lt;a href=&quot;https://t.co/qfc3Kyc9SD&quot; title=&quot;https://www.jsoftware.com/jwiki/TracyHarms/PokerHandsScoring&quot;&gt;jsoftware.com/jwiki/TracyHar…&lt;/a&gt;
&lt;/p&gt;
— Tracy Harms (&lt;span class=&quot;citation&quot; data-cites=&quot;kaleidic&quot;&gt;@kaleidic&lt;/span&gt;) &lt;a href=&quot;https://twitter.com/kaleidic/status/308298155869499393&quot;&gt;March 3, 2013&lt;/a&gt;
&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;p&gt;I can’t read J, so I can’t decide much about the quality of the code Tracy wrote, but I do notice one thing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There aren’t many functions that operate on the primitive data (card rank, card suit, hand classification), they’re close by each other, and they’re all quite short.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- more --&gt;
&lt;p&gt;Regarding this one example, then, Primitive Obsession doesn’t pose much of a problem yet. Using primitives to represent values with special constraints can lead to low cohesion and high duplication. The low cohesion consists of scattering related ideas throughout the code base, where programmers have a hard time finding them. Such scattering can lead to duplicating special processing logic, and worse, duplicating it inaccurately. That leads to mistakes. This makes me ask a question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When does Primitive Obsession not smell?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I suppose it doesn’t smell when we use other means to keep cohesion high and duplication low. We can use primitives safely when we keep the special processing logic for those primitive values close together and use willpower (effectively) to avoid duplicating it.&lt;/p&gt;
&lt;p&gt;I still can’t account for Tracy’s observation that Primitive Obsession doesn’t figure prominently in array programming, where it ought to run rampant and create serious problems. Some guesses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Teams of programmers working in these languages don’t create large, low-cohesion systems, like they do in Java/C#/C++.&lt;/li&gt;
&lt;li&gt;Teams of programmers working in these languages name things better in general, and so create fewer opportunities for misunderstanding.&lt;/li&gt;
&lt;li&gt;Teams of programmers working in these languages work together more closely in general, and so smooth over their misunderstandings more easily and more promptly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any ideas?&lt;/p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;p&gt;Martin Fowler, &lt;a href=&quot;https://link.jbrains.ca/32ZLFJJ&quot;&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt;. This book introduced me to Primitive Obsession as a code smell.&lt;/p&gt;
&lt;p&gt;Ward Cunningham, &lt;a href=&quot;https://link.jbrains.ca/UJl7q0&quot;&gt;“The CHECKS Pattern Language of Information Integrity”&lt;/a&gt;. This article includes a section on Whole Value, which counters the effects of Primitive Obsession. Whole Values should become &lt;em&gt;attractive code&lt;/em&gt; when you introduce them into a system.&lt;/p&gt;
&lt;p&gt;James Shore, &lt;a href=&quot;https://link.jbrains.ca/15tt4S8&quot;&gt;“Primitive Obsession”&lt;/a&gt;. I recommend this article to my students to learn more about Primitive Obsession.&lt;/p&gt;
&lt;p&gt;Corey Haines and J. B. Rainsberger, &lt;a href=&quot;https://link.jbrains.ca/12F96Ug&quot;&gt;“Primitive Obsession”&lt;/a&gt;. Corey and I discussed Primitive Obsession while in Bucharest in early 2010. This article includes a 14-minute video of the two of us chatting about the topic.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.coderetreat.org&quot;&gt;Code Retreat&lt;/a&gt;. We very commonly use the “no primitives” constraint at Code Retreat to encourage programmers to practise introducing Whole Values very early. I don’t &lt;em&gt;always&lt;/em&gt; design this way, but I believe that programmers should understand more deeply the differences between design with and without promitives, so I encourage them to practise.&lt;/p&gt;
</description>
        <pubDate>Mon, 04 Mar 2013 12:18:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/primitive-obsession-obsession</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/primitive-obsession-obsession</guid>
        
        
      </item>
    
      <item>
        <title>Modularity. Details. Pick One.</title>
        <description>&lt;p&gt;The bottom line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Modularity. Details. Pick &lt;strong&gt;one&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I often spend time with programmers who don’t like small methods and small classes, in spite of all the benefits of small methods and small classes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;easier to test&lt;/li&gt;
&lt;li&gt;easier to read, quicker to skim&lt;/li&gt;
&lt;li&gt;costs less to understand, less to understand at once&lt;/li&gt;
&lt;li&gt;easier to build correctly, quicker to build&lt;/li&gt;
&lt;li&gt;easier to compose into working systems&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These programmers range from feeling vaguely uncomfortable to showing strong and open antipathy towards small methods and small classes. They cite these two problems most often:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“I can’t find stuff!”&lt;/li&gt;
&lt;li&gt;“I have to click too much to see what’s happening!”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In an article titled “Why Shorter Methods Are Better”, which seems to have been removed from the internet, Kevin Rutherford reminded me of this issue. While Kevin extols the virtues of small methods, he admits that he feels both of these two things, but doesn’t tell us how he handles them. I started writing a comment on his article, but that expanded into this article. When I hear programmers complain (rightly) about these things, I offer the following two responses to them.&lt;/p&gt;
&lt;h2 id=&quot;would-searching-feel-better-than-browsing&quot;&gt;Would searching feel better than browsing?&lt;/h2&gt;
&lt;p&gt;I have paired, albeit mostly briefly, with thousands of programmers by now. To my surprise, they &lt;em&gt;browse&lt;/em&gt; or &lt;em&gt;navigate&lt;/em&gt; their code bases to find things, whereas I would insist on &lt;em&gt;searching&lt;/em&gt;. By this, I mean that they open up folders in a navigator view in their IDE, or navigate the file system, in order to locate a file containing the code that they want to read or change. This used to really bother me; in those days, &lt;a href=&quot;https://www.youtube.com/watch?v=OQXEzwXtzJ8&quot;&gt;I probably gave them a bad pair programming experience&lt;/a&gt; by asking too many annoying questions too early about microtechniques. I trained myself over time to watch them patiently, focus on the bigger picture, earn their trust, and then &lt;em&gt;eventually&lt;/em&gt; I stop them and ask:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I would typically search for that, rather than navigating to it. Do you think that might help you?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I learned over the years to stop caring &lt;em&gt;where&lt;/em&gt; to find things any more. It costs me much less in mental energy to know that “they’re somewhere in this room”&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. I navigate when searching fails me and I don’t have the energy to sharpen my searching skills. Sometimes I realize that I got the search pattern wrong; sometimes I realize that I don’t know how to use the relevant search tool; occasionally I don’t even have the faintest idea how to search for something. In those situations, I navigate, then make a note to figure out how to search for it next time. (I really like &lt;code&gt;ripgrep-all&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;The classic book &lt;a href=&quot;https://link.jbrains.ca/WNg8Se&quot;&gt;The Pragmatic Programmer&lt;/a&gt; teaches us to learn one editor well, which I try to do, but as part of classroom training and mentoring thousands of programmers, I find myself working in unfamiliar environments quite often. When I work in a new one, I spend some time learning how to search for things. And search tools don’t only mean &lt;code&gt;grep&lt;/code&gt; or &lt;code&gt;Ctrl+F&lt;/code&gt;. I look for specialized search tools, because their context-specific behavior makes them especially powerful. In Eclipse, I use “Open Type” and “Open Resource” extensively. In IntelliJ IDEA, I lean on &lt;code&gt;Ctrl+F12&lt;/code&gt; extensively (“File Structure”) to quickly find a method by some small part of its name. Before I knew anything useful about &lt;code&gt;vim&lt;/code&gt; (now &lt;a href=&quot;https://kakoune.org&quot;&gt;kakoune&lt;/a&gt;), I learned to press &lt;code&gt;/&lt;/code&gt; to find text in a file. Before I knew anything useful about Unix, I could clumsily use &lt;code&gt;grep&lt;/code&gt;, and more recently I’ve learned about &lt;code&gt;ack&lt;/code&gt;, &lt;code&gt;ag&lt;/code&gt;, &lt;code&gt;ripgrep&lt;/code&gt;, and now even &lt;code&gt;ripgrep-all&lt;/code&gt;. (Maybe I have a search tool problem; &lt;em&gt;I&lt;/em&gt; think I have a search tool solution!) I don’t use Emacs any more, but I always loved its incremental search feature. Why do I rely on searching so much? I have this computer; I want it to do the things that computers are good at. Computers &lt;em&gt;find&lt;/em&gt; things really well, especially something as simple as an exact pattern of text. Humans get that wrong too often—certainly, &lt;em&gt;I&lt;/em&gt; do.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;still&lt;/em&gt; see programmers &lt;em&gt;scan web pages with their eyes to find exact text&lt;/em&gt;, rather than use the “find in page” feature of their browser. I understand this when they’re not sure what they’re looking for, but when trying to find exact text? It surprises me every time. I’ve even enjoyed working in environments &lt;em&gt;where I don’t even know that it stores my code in &lt;strong&gt;files&lt;/strong&gt;&lt;/em&gt;!&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; (Well, I want my code in files in order to put them into a version control repository, but that’s another article.)&lt;/p&gt;
&lt;p&gt;This brings me to my other response—the one related to software design.&lt;/p&gt;
&lt;h2 id=&quot;modularity.-details.-pick-one.&quot;&gt;Modularity. Details. Pick One.&lt;/h2&gt;
&lt;p&gt;If you ask programmers whether they want more modularity in their code, many say that they do. Some of them genuinely want it and some others think that they &lt;em&gt;ought&lt;/em&gt; to want it and still others think it’s important to be seen saying that they want it. Even assuming the purest of intentions, many programmers who want more modularity don’t seem to understand that &lt;strong&gt;modularity comes from abstraction&lt;/strong&gt;, that &lt;strong&gt;abstraction literally means hiding details&lt;/strong&gt;, and that &lt;strong&gt;hiding details means moving them out of view, so that you have to go looking for them&lt;/strong&gt;. If you want to see the details here and now, that reduces modularity; and if you want more modularity, then you have to move details out of your immediate view. To those who still feel uncomfortable about this, I suggest repeating a little mantra all day today:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don’t care. I don’t need to know. &lt;strong&gt;I don’t want to know.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If that feels too informal, then I make some impressive-sounding argument with phrases like &lt;em&gt;reducing cognitive load&lt;/em&gt; and &lt;em&gt;taking advantage of chunking&lt;/em&gt;. Some people just like that kind of thing; I’m not above resorting to such tricks to help people past their own interference. I find it downright delightful when I see other people use these same tricks on me, especially when it works!&lt;/p&gt;
&lt;p&gt;Giving up your desire to see more details won’t lead you directly to writing more modular code, but &lt;strong&gt;clinging to details will keep you from it&lt;/strong&gt;. The more your code knows about its neighbors, the more it costs to change or replace those neighbors. Changes ripple out to the rest of the system. When you do this, you’re writing more legacy code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Modularity needs abstraction. Abstraction means hiding details. If you cling more to details, then you will not create enough abstractions, and you won’t achieve the modularity that you want. &lt;strong&gt;Modularity improves as you refuse to be distracted by irrelevant details.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I noticed that my designs improved once I began more-stubbornly refusing to know more than I needed to achieve my current goal. You can frame this as refusing to be burdened or as allowing yourself to let go. “I don’t care. I don’t need to know. &lt;strong&gt;I don’t want to know&lt;/strong&gt;. It’s OK not to know.”&lt;/p&gt;
&lt;h3 id=&quot;solid-effective-ignorance&quot;&gt;SOLID: Effective ignorance&lt;/h3&gt;
&lt;p&gt;Look at the SOLID principles and how they relate to letting go of the details.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Single Responsibility: I only care about what happens here right now.&lt;/li&gt;
&lt;li&gt;Open/Closed: I only care about how to make my new feature fit into the existing workflow right now. Other workflow users don’t matter to me.&lt;/li&gt;
&lt;li&gt;Liskov Substitution: I only care about the contracts of surrounding things, not their implementation details.&lt;/li&gt;
&lt;li&gt;Interface Segregation: I only care about the specific parts of surrounding things that help me achieve my goal.&lt;/li&gt;
&lt;li&gt;Dependency Inversion: I only care about what I can do without worrying about why others might use me.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I put it this way, the SOLID principles feel downright peaceful!&lt;/p&gt;
&lt;h2 id=&quot;you-dont-want-more-modularity-thats-fine-with-me.&quot;&gt;You don’t want more modularity? That’s fine with me.&lt;/h2&gt;
&lt;p&gt;I’ve assumed in this article that we &lt;em&gt;want&lt;/em&gt; more-modular systems. You might not. I didn’t intend to argue for the merits of modularity here. Instead, I only wanted to help readers who feel stuck trying to have two fundamentally contradictory things at the same time, in case they interpreted their failures as personal failures. You didn’t fail; you tried to do the impossible. You can let go now.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Modularity and fixation on details simply don’t work together. If you want one, then you need to let go of the other. Pick one.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Find and watch &lt;a href=&quot;https://www.imdb.com/title/tt0094072&quot;&gt;this film&lt;/a&gt;. Don’t be put off by the inclusion of Kirstie Alley.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I would really have loved Visual Age for Java if it didn’t corrupt the workspace so frequently.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 31 Jan 2013 14:50:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/modularity-details-pick-one</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/modularity-details-pick-one</guid>
        
        
        <category>Simple Design</category>
        
        <category>Refactoring</category>
        
      </item>
    
      <item>
        <title>Demystifying the Dependency Inversion Principle</title>
        <description>&lt;p&gt;Another “demystifying” article. Great! I know… bear with me.&lt;/p&gt;
&lt;p&gt;Of the SOLID principles, the Dependency Inversion Principle remains somewhat misunderstood. I’d like to help with that. I hope you’ll ask questions and challenge these ideas, so that I can improve this little article.&lt;/p&gt;
&lt;p&gt;I learned the Dependency Inversion Principle from &lt;a href=&quot;https://link.jbrains.ca/2sTNJ3n&quot;&gt;Bob Martin’s article&lt;/a&gt;, the salient part of which states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;High level modules should not depend upon low level modules. Both should depend upon abstractions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Abstractions should not depend upon details. Details should depend upon abstractions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’ve noticed that I spend the vast majority of my time introducing abstractions and inverting dependencies (abstractions that use concrete things) when rescuing legacy code or adding behavior to legacy systems. Sometimes I feel like I don’t know any other useful trick than &lt;em&gt;invert this dependency&lt;/em&gt;. One could make a drinking game out of it.&lt;/p&gt;
&lt;p&gt;Even so, not enough people understand and apply DIP. Perhaps if I share a few examples or equivalent formulations, they will.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id=&quot;move-specificity-towards-the-tests&quot;&gt;Move Specificity Towards the Tests&lt;/h2&gt;
&lt;p&gt;Moving details from production code towards tests clarifies the tests. In particular, I find it easier to relate the inputs to the expected outputs. It eliminates duplication between tests and production code. It highlights opportunities for abstraction and reuse. Corey Haines interviewed me about this in summer 2009.&lt;/p&gt;
&lt;figure class=&quot;body-text-block&quot;&gt;
&lt;div class=&quot;embedded-video-container&quot;&gt;
&lt;iframe class=&quot;embedded-video&quot; src=&quot;https://player.vimeo.com/video/5895145&quot; frameborder=&quot;0&quot; webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://vimeo.com/5895145&quot;&gt;JB Rainsberger - Move Specificity Towards the Tests&lt;/a&gt; from &lt;a href=&quot;https://vimeo.com/coreyhaines&quot;&gt;Corey Haines&lt;/a&gt; on &lt;a href=&quot;https://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;(If you can’t watch the embedded video, then &lt;a href=&quot;https://link.jbrains.ca/119weXi&quot;&gt;click here&lt;/a&gt;.)&lt;/p&gt;
&lt;h2 id=&quot;move-implementation-choices-up-the-call-stack&quot;&gt;Move Implementation Choices Up the Call Stack&lt;/h2&gt;
&lt;p&gt;Dependency injection confuses and annoys people, partly because some people miss the point. Injecting a dependency makes testing easier, by letting us substitute implementations in our tests that make those tests easier to write and understand. Don’t stop there. When in doubt, push &lt;code&gt;new&lt;/code&gt; up the call stack. In particular, don’t instantiate a &lt;em&gt;service&lt;/em&gt; if you can get your caller to do that. Keep pushing, even more than you think you should. Let all the choices of implementation of each service interface bubble up the call stack until they collect in your application’s or component’s entry point. This shines a huge floodlight on otherwise obscure duplication. It also paves the way for &lt;em&gt;sane&lt;/em&gt; use of a dependency injection container, even though you don’t need a container to inject dependencies well. This movement of &lt;code&gt;new&lt;/code&gt; up the call stack leaves in its wake a loosely-coupled network of abstractions talking to each other over well-defined interfaces with well-understood contracts. Using this technique helps me remove duplication, which decreases errors, particularly of the “I forgot to change that one” type. Using this technique also encourages me to write code that depends on narrower interfaces, which slowly become more generic interfaces, which makes the code depend less on its context and more suitable to use in other contexts.&lt;/p&gt;
&lt;h2 id=&quot;abstraction-in-code-details-in-metadata&quot;&gt;Abstraction in Code; Details in Metadata&lt;/h2&gt;
&lt;p&gt;I first learned this principle from the book &lt;a href=&quot;https://link.jbrains.ca/2tQl7JK&quot;&gt;The Pragmatic Programmer&lt;/a&gt;. You’ll find it as “tip 38”. I encourage you to buy the book and the read the tip yourself. The authors state among the benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a more robust program&lt;/li&gt;
&lt;li&gt;a more flexible program&lt;/li&gt;
&lt;li&gt;opportunity to reuse the “engine” with different metadata&lt;/li&gt;
&lt;li&gt;opportunity to express metadata in the language of the domain&lt;/li&gt;
&lt;li&gt;opportunity to customise code without rebuilding it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Who could argue with all that?&lt;/p&gt;
&lt;h2 id=&quot;quick-summary&quot;&gt;Quick Summary&lt;/h2&gt;
&lt;p&gt;If you agree with the specific principles I’ve cited here, then you also agree with the Dependency Inversion Principle. Said differently:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Push details up towards the client and push generic patterns down towards the server.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This principle, applied everywhere, makes testing easier, promotes reuse, both of which reduce the incidence of errors and the cost of development.&lt;/p&gt;
&lt;p&gt;So tell me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you already felt you understood the DIP well, how faithfully did I represent it here?&lt;/li&gt;
&lt;li&gt;If you didn’t quite understand the DIP well before, how much has this article helped or hindered your understanding?&lt;/li&gt;
&lt;li&gt;If you explain the DIP to others, how do you do it?&lt;/li&gt;
&lt;li&gt;If you still think the DIP is a load of nonsense, how do you justify that? I’d like the chance to help you as well as fix holes in my own understanding and reasoning.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;one-more-thing&quot;&gt;One More Thing&lt;/h2&gt;
&lt;div data-markdown=&quot;1&quot; style=&quot;font-size: 80%&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In what follows, I refer to the &lt;a href=&quot;https://projects.spring.io/spring-framework/&quot;&gt;Spring framework&lt;/a&gt;’s dependency injection container, not the &lt;a href=&quot;https://github.com/rails/spring&quot;&gt;Rails Spring application preloader&lt;/a&gt;. I didn’t even know that the latter existed until a commenter and I confused each other by using the same words to mean different things. (If you have a spare 50 minutes, you can &lt;a href=&quot;https://vimeo.com/78917211&quot;&gt;watch a video&lt;/a&gt; in which I discuss this and other tricks to improve how we programmers communicate with the world.)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;p&gt;If you hate Spring’s dependency injection container, then I know why: you have code that &lt;em&gt;depends&lt;/em&gt; on the container.&lt;/p&gt;
&lt;p&gt;Don’t do that.&lt;/p&gt;
&lt;p&gt;Dependency injection is related to the Inversion of Control principle, also known as the Hollywood Principle:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don’t call us; we’ll call you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Spring’s dependency injection container calls you; you never call it. Never.&lt;/p&gt;
&lt;p&gt;Fine: you call it only from a smoke test that verifies that you’ve wired up your dependencies correctly, but you &lt;strong&gt;never call your dependency injection container from production code&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Bob Martin, &lt;a href=&quot;https://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod&quot;&gt;“Principles of OOD (Object-Oriented Design)”&lt;/a&gt;. A collection of Bob’s original papers on the SOLID principles, among others.&lt;/p&gt;
</description>
        <pubDate>Tue, 29 Jan 2013 16:55:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/consequences-of-dependency-inversion-principle</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/consequences-of-dependency-inversion-principle</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
        <category>Surviving Legacy Code</category>
        
      </item>
    
      <item>
        <title>The Liskov Substitution Principle Demystified</title>
        <description>&lt;p&gt;I apologise for the pompous title; I wrote it just for fun. If this “demystifies” anything, I’ll consider that a coincidence.&lt;/p&gt;
&lt;p&gt;Of the SOLID principles, the most pompous-sounding is the one named for a person: Barbara Liskov. I don’t label her pompous – I never knew her – but of those five principles, only LSP has a common formulation that looks like the kind of mathematics so many programmers like to avoid, while others flock to.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let &lt;em&gt;q(x)&lt;/em&gt; be a property provable about objects &lt;em&gt;x&lt;/em&gt; of type &lt;em&gt;T&lt;/em&gt;. Then &lt;em&gt;q(y)&lt;/em&gt; should be provable for objects &lt;em&gt;y&lt;/em&gt; of type &lt;em&gt;S&lt;/em&gt; where &lt;em&gt;S&lt;/em&gt; is a subtype of &lt;em&gt;T&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or, if you prefer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Subtypes must not change any supertype’s significant behavior. Here, “significant behavior” means behavior upon which clients of those objects expressly depend.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you like the language of contracts, then you might prefer this formulation: &lt;!-- more --&gt; &amp;gt; Subtypes must respect the contracts of their supertypes.&lt;/p&gt;
&lt;p&gt;If, like me, you like to check contract compliance with &lt;a href=&quot;https://link.jbrains.ca/13e1S9Y&quot;&gt;contract tests&lt;/a&gt;, then you might prefer &lt;em&gt;this&lt;/em&gt; formulation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Subtypes must pass the same set of contract tests that their supertypes pass.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Remember that &lt;em&gt;subtype&lt;/em&gt; here means any implementation of an interface or subclass of a class.&lt;/p&gt;
&lt;p&gt;So, what does it look like when we violate the Liskov Substitution Principle? Usually like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// This should never happen&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can’t trace &lt;em&gt;all&lt;/em&gt; such problems to a violation of LSP. Sometimes you have a simpler disagreement between a client and its collaborator. Even so, subtyping without careful attention to the type’s contract opens the door wide to breaking the contract, which creates disagreement between a client and a collaborator whose type &lt;em&gt;we sometimes only know at runtime&lt;/em&gt;. You’ve experienced this if you’ve ever ended a 2-hour-long debugging session by yelling “You idiot! How did you expect that &lt;em&gt;ever&lt;/em&gt; to work?!” You’ve discovered a fundamental contract disagreement.&lt;/p&gt;
&lt;p&gt;While the LSP doesn’t receive the same attention as the Single Responsibility Principle, breaking the LSP leads to painful, costly mistakes. Understanding LSP, clarifying and respecting contracts helps you avoid this frustration.&lt;/p&gt;
&lt;p&gt;I hope this helps.&lt;/p&gt;
</description>
        <pubDate>Tue, 08 Jan 2013 14:03:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/liskov-substitution-principle-demystified</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/liskov-substitution-principle-demystified</guid>
        
        
      </item>
    
      <item>
        <title>Inquisition By Contract</title>
        <description>&lt;p&gt;Just a fun link today.&lt;/p&gt;
&lt;p&gt;I read about Design by Contract first, didn’t understand it, then read about Test-Driven Development and began to think of TDD as a kind of DbC by example. Accordingly, I have respect for both practices and have even combined them on projects. Moreover, “&lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;Integrated Tests are a Scam&lt;/a&gt;” amounts to little more than Isolating Layers by Contract.&lt;/p&gt;
&lt;p&gt;When I saw &lt;a href=&quot;https://link.jbrains.ca/Wnd5i1&quot;&gt;the Vigil programming language&lt;/a&gt; today, I fell in love. To quote its README:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When a Vigil program is executed, Vigil itself will monitor all oaths (implorations and swears) that have been made. If an oath is broken, the offending function (the caller in the case of implore and the callee in the case of swear) will be duly punished.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I know for sure I’ll try Vigil at the next &lt;a href=&quot;https://www.coderetreat.org&quot;&gt;Code Retreat&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Thu, 03 Jan 2013 14:47:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/inquisition-by-contract</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/inquisition-by-contract</guid>
        
        
      </item>
    
      <item>
        <title>Publish posts later with Jekyll/Octopress</title>
        <description>&lt;style type=&quot;text/css&quot;&gt;
span.keep-together { white-space: nowrap; }
&lt;/style&gt;
&lt;p&gt;I really like Octopress, which is built on Jekyll. You can read a lot of articles about the advantages and disadvantages of pre-baked blogs, so I won’t bore you with those details. Instead, I’ll bore you on the subject of the one feature I miss with pre-baked blogs: scheduling posts for later publication.&lt;/p&gt;
&lt;p&gt;When I switched to a pre-baked blogging tool like Octopress, I gave up the ability to upload a post, but publish it later. Well, I didn’t really give it up entirely, but pre-baking my blog means thinking of my blog as a static web site, rather than a dynamic one, which implies having to re-deploy every time I wanted to change its content. This makes scheduling posts in the future a bit more tricky.&lt;/p&gt;
&lt;p&gt;Using Heroku and its read-only file system make it even trickier, since I can’t regenerate the blog in production.&lt;/p&gt;
&lt;p&gt;I just wanted to share my solution with you, in case it interests you. &lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;First, I added to Octopress the ability to generate the blog without future-dated posts. This looked difficult, especially with Octopress’s existing “preview mode” feature, but I discovered that Jekyll supports omitting future-dated posts directly with &lt;span class=&quot;keep-together&quot;&gt;&lt;code&gt;jekyll --no-future&lt;/code&gt;&lt;/span&gt;, so I augmented Octopress to use this feature. If you’d like to explore the details, &lt;a href=&quot;https://link.jbrains.ca/11rxWGB&quot;&gt;click here&lt;/a&gt;.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, I needed a way to republish my Octopress site regularly in order to include new posts as their publication instant arrives. I asked my tweeps for ideas, and we agreed that we couldn’t get around having a machine Out There Somewhere that’s always on that would poll a &lt;code&gt;git&lt;/code&gt; repository for changes, then regenerate and publish to Heroku. I settled on the following architecture.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/PublishLater-Octopress-Heroku/blog-architecture.png&quot; alt=&quot;You can smell the Architecture!&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;You can smell the Architecture!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I followed these basic steps:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Added an SSH public key from “Monitor/Staging” to “Production”, so that the former could &lt;code&gt;push&lt;/code&gt; to the latter.&lt;/li&gt;
&lt;li&gt;Installed a script into “Monitor/Staging” to, well, monitor, stage, then &lt;code&gt;push&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Cloned my local &lt;code&gt;git&lt;/code&gt; repository to “Integration” so that it will always be available to “Monitor/Staging”.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Complicated, sure, but–and you’ll tell me if you disagree–just barely sufficiently complicated, and no worse. I can handle that.&lt;/p&gt;
&lt;p&gt;My workflow hasn’t changed much. I compose posts, preview, and &lt;code&gt;push&lt;/code&gt; to “Integration” when I finish. “Monitor/Staging” runs the following script every 10 minutes.&lt;/p&gt;
&lt;p&gt;#! /bin/bash pushd $HOME/Workspaces/blog.thecodewhisperer.com # I have to do this by hand, apparently. . .rvmrc&lt;/p&gt;
&lt;h1 id=&quot;i-cant-assume-that-im-on-the-right-branch&quot;&gt;I can’t assume that I’m on the right branch&lt;/h1&gt;
&lt;p&gt;git checkout -q master git pull -q origin master git checkout -q publish git merge -q master&lt;/p&gt;
&lt;h1 id=&quot;check-the-diff-before-regenerating-to-avoid-spurious&quot;&gt;Check the diff /before/ regenerating, to avoid spurious&lt;/h1&gt;
&lt;h1 id=&quot;timestamp-differences&quot;&gt;timestamp differences&lt;/h1&gt;
&lt;p&gt;DIFF=“&lt;span class=&quot;math inline&quot;&gt;$(git diff --stat publish heroku/master)&quot; NOW=`date` if [ -n &quot;$&lt;/span&gt;DIFF” ]; then echo “Publishing $NOW…” bundle exec rake generate git add -A &amp;amp;&amp;amp; git commit -m “Published $NOW” &amp;amp;&amp;amp; git push heroku publish:master else echo “No need to publish at $NOW.”; fi popd&lt;/p&gt;
&lt;p&gt;I write posts to the branch &lt;code&gt;master&lt;/code&gt;, and “Monitor/Staging” merges them to the branch &lt;code&gt;publish&lt;/code&gt;, then deploys them to “Production”’s branch &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Of course, I will monitor this closely over the next few days, looking for anomalies. In particular, I worry a little about what happens when “Monitor/Staging” can’t merge &lt;code&gt;master&lt;/code&gt; to &lt;code&gt;publish&lt;/code&gt; automatically. I suppose in that case I’ll have something to worry about, and in the worst case, no changes will publish to production, which could cause annoyance, but sounds like safe default behavior.&lt;/p&gt;
&lt;p&gt;If you see any problems with this setup, please don’t keep them to yourself!&lt;/p&gt;
&lt;h2 id=&quot;theres-more&quot;&gt;There’s More!&lt;/h2&gt;
&lt;p&gt;In 2014 Jason Fox of &lt;a href=&quot;https://www.neverstopbuilding.com&quot;&gt;neverstopbuilding.com&lt;/a&gt; wrote about how he used Heroku to run a little blog updating application that wakes up on a schedule and tries to publish queued-up posts. He used this article as a jumping-off point. Finally, after two years of looking, I found Jason’s article and adapted his approach for myself, rather than needing to run own custom process on a custom server somewhere. I plan to replace this sentence with details on how I did it and a link to a repository you can use as the starting point for solving this problem for yourself. If I haven’t done this by December 1, 2014, then &lt;a href=&quot;https://tell.jbrains.ca&quot;&gt;tell me&lt;/a&gt; that I haven’t done it yet. Be sure to link to this article.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Jason Fox, &lt;a href=&quot;https://bit.ly/1w2RjEq&quot;&gt;&lt;em&gt;Simple Queuing of Jekyll Posts with Heroku (or How to Have Heroku Push to Heroku)&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I’ve submitted a &lt;a href=&quot;https://link.jbrains.ca/11Hde4E&quot;&gt;pull request&lt;/a&gt; for this, but I think Octopress’s maintainer has other, more important stuff to do these days.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 06 Dec 2012 12:52:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/publish-posts-later-with-jekyll-slash-octopress</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/publish-posts-later-with-jekyll-slash-octopress</guid>
        
        
      </item>
    
      <item>
        <title>Announcing a New Book</title>
        <description>&lt;p&gt;I’m pleased to announce that I have started writing a new book, entitled &lt;a href=&quot;https://link.jbrains.ca/SpIUHM&quot;&gt;&lt;em&gt;Responsible Design for Android&lt;/em&gt;&lt;/a&gt;. I really envision this as a &lt;em&gt;series of short books&lt;/em&gt;, not wanting to repeat the 750-page behemoth that was &lt;a href=&quot;https://link.jbrains.ca/TEDGGm&quot;&gt;JUnit Recipes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Part 1, &lt;em&gt;Dancing with the Android SDK&lt;/em&gt;, I explore a sensible architecture for the basic Android app, emphasising &lt;em&gt;context independence&lt;/em&gt; to avoid letting the Android framework swallow my app whole. I use tactics that have worked to great effect in working with older frameworks such as Servlets and EJB.&lt;/p&gt;
&lt;p&gt;I toyed with the idea of writing an Android app in Ruby using Rhodes, but decided to return to my roots and Java, so if you’re writing Android apps in Java, and have run into maintenance or extensibility problems, then I’m writing this book for you.&lt;/p&gt;
&lt;p&gt;I say “I’m writing”, because I’ve decided to use &lt;a href=&quot;https://www.leanpub.com&quot;&gt;LeanPub&lt;/a&gt; to compose and publish the book. This means that you can read the book as I write it, and your feedback and questions could help direct its contents. As of this writing, I’ve published three versions of the book, and plan to publish a new version approximately twice per week until I’ve written enough.&lt;/p&gt;
&lt;p&gt;The sooner you purchase the book, the less you pay, and once you purchase the book, you receive all future updates free of charge. I have already raised the minimum price of the book once, as I have published more content.&lt;/p&gt;
&lt;p&gt;If you’d like to take a look, &lt;a href=&quot;https://link.jbrains.ca/XfFImB&quot;&gt;click here&lt;/a&gt; to download a sample chapter, then &lt;a href=&quot;https://link.jbrains.ca/SpIUHM&quot;&gt;click here&lt;/a&gt; to buy the book.&lt;/p&gt;
</description>
        <pubDate>Mon, 03 Dec 2012 14:03:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/announcing-a-new-book</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/announcing-a-new-book</guid>
        
        
      </item>
    
      <item>
        <title>A new twist on an old pattern</title>
        <description>&lt;p&gt;I’m coding like it’s 2000, meaning in Java. I thought I’d never see anything new regarding writing a test that expects to catch a specific exception. I saw something new, and I wonder who else has independently discovered it.&lt;/p&gt;
&lt;figure&gt;
&lt;pre&gt;
@Test
public void ioFailure() throws Exception {
    final IOException ioFailure = new IOException(&quot;Simulating a failure writing to the file.&quot;);
    try {
        new WriteTextToFileActionImpl() {
            @Override
            protected FileWriter fileWriterOn(File path) throws IOException {
                return new FileWriter(path) {
                    @Override
                    public void write(String str, int off, int len) throws IOException {
                        throw ioFailure;
                    }
                };
            }
        }.writeTextToFile(&quot;::text::&quot;, new File(&quot;anyWritableFile.txt&quot;));
        fail(&quot;How did you survive the I/O failure?!&quot;);
    } catch (IOException success) {
        if (success != ioFailure)
            throw success;
    }
}
 
&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Please add your comments at &lt;a href=&quot;https://gist.github.com/jbrains/4111662#comments&quot;&gt;gist.github.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;(If you can’t see the code snippet inline, then &lt;a href=&quot;https://gist.github.com/jbrains/4111662&quot;&gt;click here&lt;/a&gt;.)&lt;/p&gt;
</description>
        <pubDate>Mon, 19 Nov 2012 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-new-twist-on-an-old-pattern</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-new-twist-on-an-old-pattern</guid>
        
        
      </item>
    
      <item>
        <title>10 Ways to Kill Your Design</title>
        <description>&lt;p&gt;I wish that I could take credit for this article, but I can’t. Instead, I have to credit two people: &lt;a href=&quot;https://www.twitter.com/#!/lassekoskela&quot;&gt;Lasse Koskela&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/#!/mhevery&quot;&gt;Miško Hevery&lt;/a&gt;. I credit Lasse for writing the manuscript that led me to Miško’s article. Look for Lasse’s upcoming book &lt;em&gt;Unit Testing in Java&lt;/em&gt; &lt;a href=&quot;https://manning.com/koskela2/&quot;&gt;at Manning Publications’ site&lt;/a&gt;. Let me summarize Miško’s article here, then you can read the details at &lt;a href=&quot;https://misko.hevery.com/2008/07/30/top-10-things-which-make-your-code-hard-to-test/&quot;&gt;his blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Why would I simply summarize someone else’s article on this site? Isn’t that dishonest? Not in this case: Miško wrote essentially the same thing that I say over and over again in my own articles and in my training classes. I consider it unfortunate that he and I have never met nor worked together. We really should. You should read his stuff.&lt;/p&gt;
&lt;p&gt;So… 10 ways to kill your design.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Instantiate &lt;a href=&quot;/permalink/when-is-it-safe-to-introduce-test-doubles&quot;&gt;Services&lt;/a&gt; wherever the hell you want.&lt;/li&gt;
&lt;li&gt;Grab what you want when you want it.&lt;/li&gt;
&lt;li&gt;Do real work in your constructors.&lt;/li&gt;
&lt;li&gt;Make state easily changed by clients.&lt;/li&gt;
&lt;li&gt;Embrace singletons.&lt;/li&gt;
&lt;li&gt;Make methods &lt;code&gt;static&lt;/code&gt;. (Admittedly, this is more of a problem in Java/C# than Ruby/Python.)&lt;/li&gt;
&lt;li&gt;Inherit implementation.&lt;/li&gt;
&lt;li&gt;Reimplement polymorphism.&lt;/li&gt;
&lt;li&gt;Mix &lt;a href=&quot;/permalink/when-is-it-safe-to-introduce-test-doubles&quot;&gt;Services and Values&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Keep &lt;a href=&quot;https://dictionary.reference.com/browse/conjunction&quot;&gt;conjunctions&lt;/a&gt; in your variable, method and class names.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://misko.hevery.com/2008/07/30/top-10-things-which-make-your-code-hard-to-test/&quot;&gt;Read more about the problems that these “techniques” cause&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Feb 2012 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/ten-ways-to-kill-your-design</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/ten-ways-to-kill-your-design</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>From dependent tests to independent tests to independent assertions</title>
        <description>&lt;p&gt;&lt;span style=&quot;float: right; margin-left: 10px; margin-bottom: 10px; width: 3cm&quot;&gt;&lt;img src=&quot;/images/dhemery-small.jpg&quot; alt=&quot;Dale Emery&quot; /&gt;&lt;/span&gt; [We might choose to] write tests so that a failure in a predecessor test causes dependent tests not to execute. In object tests, we do this by writing a test method with multiple assertions. – Dale Emery&lt;/p&gt;
&lt;p&gt;When multiple assertions check very tightly related things, I don’t mind them, but when they check relatively loosely related things, they act as integrated tests for multiple behaviors that we should consider separating. This is even subtler than the simpler idea of “one action per test”.&lt;/p&gt;
&lt;p&gt;If you’d like a &lt;strong&gt;Novice algorithm&lt;/strong&gt; to follow:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Look for any test with multiple assertions.&lt;/li&gt;
&lt;li&gt;Move those assertions to the bottom of the test. (If they aren’t already at the bottom, then you might have more than one action per test; this refactoring will help you discover that.)&lt;/li&gt;
&lt;li&gt;Extract all the assertions together into a single method.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now look at the new method. How many different objects does the method use?&lt;/p&gt;
&lt;p&gt;If it’s more than one, then you almost certainly have unrelated assertions in the same place, so consider splitting the unrelated assertions into separate methods, then split the test into two so that each test invokes one of the two new separated assertion methods.&lt;/p&gt;
&lt;p&gt;If your new assertion method uses only one object, then it might not be so clear whether those assertions are related. You can try this simple test: put all the values you’re checking in your assertions into a single object. Can you think of a good name for it? If yes, then perhaps you’ve just identified a missing abstraction in your system; and if not, then perhaps the assertions have too little to do with each other, in which case, try the trick in the preceding paragraph.&lt;/p&gt;
&lt;p&gt;I apologise for not having a good example of this right now. If you point me to one, I’ll analyse it in this space.&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Dec 2011 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/from-dependent-tests-to-independent-tests-to-independent-assertions</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/from-dependent-tests-to-independent-tests-to-independent-assertions</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Stop. Write a Learning Test.</title>
        <description>&lt;h2 id=&quot;the-30-second-version&quot;&gt;The 30-second version&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.google.com/search?q=yak+shaving&quot;&gt;Where did that yak come from?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;When you try to learn a new library at the same time as explore the behavior and design of your application, you slow down more than you think.&lt;/li&gt;
&lt;li&gt;When you can’t figure out how to make the new library work for this thing you want to build, you might spend hours fighting, debugging, swearing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stop. Write a Learning Test.&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Start a new test suite, test class, spec file, whatever you want to call it.&lt;/li&gt;
&lt;li&gt;Write a test that checks the things you tried to check earlier with debug statements.&lt;/li&gt;
&lt;li&gt;Write a test that has nothing to do with your application and its domain.&lt;/li&gt;
&lt;li&gt;Remove unnecessary details from your test.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When this test passes, then you understand what that part of the library does. If it behaves strangely, then you have the perfect test to send to the maintainers of the library.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id=&quot;the-details&quot;&gt;The Details&lt;/h2&gt;
&lt;p&gt;I just did this on a project using the context-free grammar parser &lt;a href=&quot;https://github.com/nathansobo/treetop&quot;&gt;&lt;em&gt;treetop&lt;/em&gt;&lt;/a&gt;. Of course, I hadn’t used &lt;em&gt;treetop&lt;/em&gt; before, so I had to learn it at the same time as design the grammar for the language I wanted to parse. I reached the point where I couldn’t write a &lt;em&gt;grammar rule&lt;/em&gt; correctly, and spent probably an hour trying to figure out get it to work.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; Fortunately, at that moment, my laptop ran out of power, so I left the coffee shop&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; and did the usual thing: &lt;a href=&quot;https://c2.com/cgi/wiki?RubberDucking&quot;&gt;I explained the problem to my wife (herself not a programmer) so that I could hear myself doing that&lt;/a&gt;. After about 15 minutes away from the problem, I decided to write some &lt;a href=&quot;https://c2.com/cgi/wiki?LearningTest&quot;&gt;Learning Tests&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;summary-of-what-i-did&quot;&gt;Summary of what I did&lt;/h2&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;I wrote a Learning Test for a simple case that I thought I already understood well.&lt;/li&gt;
&lt;li&gt;I wrote a Learning Test similar to the problem I had to deal with, to make sure I understood &lt;em&gt;that&lt;/em&gt; well.&lt;/li&gt;
&lt;li&gt;I wrote a Learning Test for the exact case that behaved unexpectedly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The whole thing took an hour, and I understood the problem well enough to explain it to a non-programmer, my wife. She understood it and agreed that it sounded like a mistake in the library.&lt;a href=&quot;#fn4&quot; class=&quot;footnote-ref&quot; id=&quot;fnref4&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt; I used this Learning Test to open an issue at github. Now I can proceed without pulling my own hair out.&lt;/p&gt;
&lt;h2 id=&quot;do-you-want-to-see-the-learning-tests&quot;&gt;Do you want to see the Learning Tests?&lt;/h2&gt;
&lt;p&gt;This is the case I already understood well:&lt;/p&gt;
&lt;pre&gt;
require &apos;treetop&apos;

describe &quot;Grammar with a simple rule&quot; do
  let(:subject) { Treetop.load_from_string(
&amp;lt;&amp;lt;GRAMMAR
grammar SimpleRule
  rule word
    [A-Za-z]+
  end
end
GRAMMAR
  )}

  let (:parser) { subject.new }

  it &quot;doesn&apos;t match empty string&quot; do
    parser.parse(&quot;&quot;).should be_false
  end

  context &quot;matching single letter, the match result&quot; do
    let(:result) { parser.parse(&quot;a&quot;) }

    it { result.should be_true }
    it { result.text_value.should == &quot;a&quot; }
    it { result.to_s.should_not == &quot;a&quot; }
    it { result.should_not respond_to(:word) }
  end

  context &quot;matching many letters, the match result&quot; do
    let(:result) { parser.parse(&quot;aBcDeF&quot;) }

    it { result.should be_true }
    it { result.text_value.should == &quot;aBcDeF&quot; }
    it { result.to_s.should_not == &quot;aBcDeF&quot; }
    it { result.should_not respond_to(:word) }
  end
end
&lt;/pre&gt;
&lt;p&gt;These are the cases I wasn’t sure I understood:&lt;/p&gt;
&lt;pre&gt;
require &apos;treetop&apos;

describe &quot;Grammar with a simple rule that uses a label&quot; do
  context &quot;Labeled subexpression followed by another expression&quot; do
    let(:subject) { Treetop.load_from_string(
&amp;lt;&amp;lt;GRAMMAR
grammar SimpleRuleWithLabel
  rule word
    letters:[A-Za-z]+ [A-Za-z]*
  end
end
GRAMMAR
    )}

    let (:parser) { subject.new }

    context &quot;matching many letters, the match result&quot; do
      let(:result) { parser.parse(&quot;aBcDeF&quot;) }

      it { result.should respond_to(:letters) }
      it { result.letters.text_value.should == &quot;aBcDeF&quot; }
    end
  end

  context &quot;Labeled subexpression without another expression&quot; do
    it &quot;does not represent a valid grammar, even though I think it should&quot; do
      lambda {
        Treetop.load_from_string(
&amp;lt;&amp;lt;GRAMMAR
grammar SimpleRuleWithLabel
  rule word
    letters:[A-Za-z]+
  end
end
GRAMMAR
      )}.should raise_error(RuntimeError, /Expected \#/)
    end

    it &quot;really should let me refer to the expression as #letters&quot; do
      pending &quot;https://github.com/nathansobo/treetop/issues/21&quot;
    end
  end
end
&lt;/pre&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Remember, we don’t call them bugs anymore: we call them “mistakes”. In this case, we can’t call it a “mistake” yet, because we might simply have a difference of opinion or mindset.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Note the wording: I already assuming that &lt;em&gt;I&lt;/em&gt; have it right and &lt;em&gt;they&lt;/em&gt; have it wrong. Bad programmer.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;They have a Second Cup in Romania. Canadians get why I’d find that weird.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn4&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;Smart woman, my wife.&lt;a href=&quot;#fnref4&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Wed, 14 Dec 2011 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/when-to-write-learning-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/when-to-write-learning-tests</guid>
        
        
      </item>
    
      <item>
        <title>Refactor Your Way to a Dependency Injection Container</title>
        <description>&lt;h2 id=&quot;the-30-second-version&quot;&gt;The 30-second version&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Invert the dependency on a Service, moving the &lt;code&gt;new&lt;/code&gt; statement up one level in the call stack.&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Repeat for all dependencies on Services until the corresponding &lt;code&gt;new&lt;/code&gt; statements arrive at your application’s entry point. The entry point now creates a large object graph of all your Services in its &lt;code&gt;initialize&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Remove duplication in &lt;code&gt;EntryPoint.initialize()&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;Instantiate common objects only once, passing them into the necessary constructors, replacing any Singletons with plain objects.&lt;/li&gt;
&lt;li&gt;Extract the choice of implementation for each Service interface into a lookup table mapping interface type to implementation type.&lt;/li&gt;
&lt;li&gt;Externalise the lookup table to a file, if you like.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now you have a customised Dependency Injection Container for your application. To go a little farther:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remove duplication in &lt;code&gt;EntryPoint.initialize()&lt;/code&gt; among three applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now you have a generic Dependency Injection Container that probably provides 80% or more of the features you’ll ever need.&lt;/p&gt;
&lt;p&gt;I recommend trying this incrementally. Think of the &lt;code&gt;new&lt;/code&gt; statements flowing up the call stack, into the entry point, then changing from code into data. Nice, no?&lt;/p&gt;
&lt;h2 id=&quot;the-details&quot;&gt;The Details&lt;/h2&gt;
&lt;p&gt;I don’t have much to add.&lt;/p&gt;
&lt;p&gt;I hope this helps to demystify dependency injection containers. To read about the technique of injecting dependencies, I refer you to &lt;a href=&quot;https://link.jbrains.ca/vN1IiF&quot;&gt;one of my articles&lt;/a&gt; and then &lt;a href=&quot;https://www.google.com/search?q=dependency+injection&quot;&gt;a trusty web search&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This technique applies the &lt;a href=&quot;https://www.objectmentor.com/resources/articles/dip.pdf&quot;&gt;Dependency Inversion Principle&lt;/a&gt; repeatedly to move the choice of implementation for an interface up the call stack. This way, concrete things depend on abstract things.&lt;/p&gt;
&lt;p&gt;Removing duplication in the entry point respects the principle &lt;a href=&quot;https://link.jbrains.ca/s2V3Co&quot;&gt;Abstractions in Code, Details in Data&lt;/a&gt;, but it does rely on reflection, which can cause some problems. All the better not to scatter this reflection throughout the code causing a serious cohesion problem. Using reflection like this, all in one place, helps balance using a powerful technique with a design that everyone can understand.&lt;/p&gt;
&lt;p&gt;Now you know what about 70% of what a dependency injection container does. You can build one. Even if you don’t go that far, the Dependency Inversion Principle will help reducing coupling and highlight cohesion problems in your design. It provides &lt;a href=&quot;https://link.jbrains.ca/gmeMhh&quot;&gt;another set of mechanics to practise on the way to becoming an accomplished designer&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Loose Couplings, &lt;a href=&quot;https://www.loosecouplings.com/2011/01/dependency-injection-using-di-container.html&quot;&gt;“Dependency Injection != using a DI Container”&lt;/a&gt;. A handy overview of using dependency injection containers, notably a reminder that the container ought to &lt;em&gt;enchance&lt;/em&gt; your use of dependency injection, and not interfere with it.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I mean “Service” in the &lt;a href=&quot;https://link.jbrains.ca/6AtyK&quot;&gt;Domain-Driven Design&lt;/a&gt; sense.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Wed, 07 Dec 2011 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/refactor-your-way-to-a-dependency-injection-container</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/refactor-your-way-to-a-dependency-injection-container</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Rescuing Legacy Code by Extracting Pure Functions</title>
        <description>&lt;p&gt;After running a handful of &lt;a href=&quot;https://www.legacycoderetreat.org&quot;&gt;Legacy Code Retreats&lt;/a&gt; I’ve had the chance to try a number of exercises related to rescuing legacy code. I’d like to share one that has met with very positive reactions from people: extracting &lt;em&gt;pure functions&lt;/em&gt;. I use the term &lt;em&gt;pure function&lt;/em&gt; to describe a function that only operates on local variables and parameters, but does not touch any state outside the function. No object fields, no global data. I have very little experience in functional programming, so I hope I use the term in a standard way.&lt;/p&gt;
&lt;p&gt;No doubt you already know about the &lt;a href=&quot;https://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html&quot;&gt;Composed Method&lt;/a&gt; design pattern, which we commonly use to help understand code as we read it. Most commonly you encounter a block of code with a comment that describes what that code does. You then extract that block of code into a method whose name matches the comment. I’ve used this technique for well on a decade to raise the level of abstraction in code, help code document itself, and eliminate misleading comments. While introducing these methods helps me read the code, it sometimes hides the tangle of dependencies that makes separating responsibilities so difficult. For this reason, I recommend trying to extract pure functions instead.&lt;/p&gt;
&lt;p&gt;To introduce a pure function, start with a block of code and extract a method for it. Now look at all the fields and global variables that the method reads and introduce each one as a parameter to the method. Now look at all the fields and global variables that the method writes to and turn these into return values. Where the old code invokes the new function, assign each new return value to the corresponding field or global variable. You know you’ve done this correctly if, of course, the overall behhavior of the program hasn’t changed and you can mark the new function as &lt;code&gt;static&lt;/code&gt; or whatever your language calls a class-level function.&lt;/p&gt;
&lt;p&gt;In some languages, like Java, you’ll have to introduce a new little class to allow you to return multiple values from the new function. If you don’t want to do that right away, then return a &lt;code&gt;Map&lt;/code&gt; of return values. Once you see that you need to return similar &lt;code&gt;Map&lt;/code&gt;s from different functions, consider replacing those &lt;code&gt;Map&lt;/code&gt;s with a new class. Perhaps that new class will attract some code!&lt;/p&gt;
&lt;p&gt;When I’ve used this technique, two key things have happened: either I’ve noticed duplication in the parameter lists of the new functions or introducing a parameter has changed the behavior of the system. In the first case, I introduce Parameter Objects for the duplicated parameters, which then probably attract code and become useful domain objects. In the second case, I’ve detected temporal coupling, which requires me to separate the function into two smaller ones so that some output from the first becomes input to the second. This helps me uncover cohesion problems, usually of the type of different things written too close together.&lt;/p&gt;
&lt;p&gt;I realize that an example would help right about now, but I would rather create some screencasts than write out examples in code, but I don’t know when exactly I intend to do that. I wanted to share this idea with you without waiting for the energy to put together a suitable screencast.&lt;/p&gt;
&lt;p&gt;I invite you to try introducing pure functions into some legacy code and practising the technique as a kata. Get used to the various maneuvers, like introducing Parameter Objects or Return Value Objects or solving temporal coupling by splitting the function in two. It sounds crazy, but I’d like to try a Legacy Code Retreat where we practise only this technique all day. I don’t know whether anyone else would find it valuable enough to try it together for an entire day, over and over and over.&lt;/p&gt;
&lt;p&gt;Would you? Add your comments below.&lt;/p&gt;
</description>
        <pubDate>Sun, 27 Nov 2011 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/rescuing-legacy-code-by-extracting-pure-functions</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/rescuing-legacy-code-by-extracting-pure-functions</guid>
        
        
      </item>
    
      <item>
        <title>Detecting Changes in Third-Party Code</title>
        <description>&lt;p&gt;One of the people who watched &lt;a href=&quot;https://www.infoq.com/presentations/integration-tests-scam&quot;&gt;the 2009 version of Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)&lt;/a&gt; recently asked me: &lt;em&gt;I wonder how you deal with updates of third-party libraries. How do you detect subtle API or behaviour changes? At the moment, I write state-based integration tests for these cases and I wonder whether this isn’t a sensible use of integration tests.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I write Learning Tests to discover how a third-party library works. I isolate myself from the third-party library through a layer of interfaces and adapter classes that evolve from the common ways I use the third-party library. I call this the “Pattern of Usage API”, as it represents the way my application uses that third-party library. Now my application uses the third-party library through a layer of interfaces, which means that I can introduce Contract Tests on those interfaces. These Contract Tests effectively describe the subset of the third-party library’s behavior on which I depend.&lt;/p&gt;
&lt;p&gt;Now when I upgrade the third-party library, I run the Contract Tests against my adapters to that library. Test failures usually indicate a backwards incompatible change in the third-party library. (Sometimes they indicate a trivial difference in the API which requires a trivial fix, such as an API call having been renamed or something.)&lt;/p&gt;
&lt;p&gt;Of course, this only helps me detect behavior changes related to computing answers, and not related to responsiveness, reliability, scalability, and so on. For that, I’ll always need system tests.&lt;/p&gt;
&lt;p&gt;The Contract Tests are almost always state-based integration tests. I simply limit these to the implementation of Pattern of Usage API and don’t let it leak farther up the call stack. At some point you have to integrated with the Outside World. I simply teach people to look to make that integration thinner.&lt;/p&gt;
</description>
        <pubDate>Sat, 26 Nov 2011 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/detecting-changes-in-third-party-code</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/detecting-changes-in-third-party-code</guid>
        
        
      </item>
    
      <item>
        <title>When should I remove duplication?</title>
        <description>&lt;p&gt;As I learn to become a better programmer, I continue to follow &lt;a href=&quot;https://link.jbrains.ca/g9P6Jw&quot;&gt;the four elements of simple design&lt;/a&gt;. Of these, I have observed that “remove duplication” helps me discover an appropriate structure for the thing I want to build. In my classes, we practise removing duplication a lot, in part because most people understand the rule “remove duplication” well enough to find it useful. After the first few weeks of practice, however, programmers following this rule observe varying results: sometimes removing the duplication makes the design much clearer, and sometimes it muddies the water. At this stage, she usually looks for more detailed rules to help decide when to remove duplication and when to leave it alone. I offer some simple rules and guidelines for this situation.&lt;/p&gt;
&lt;p&gt;When I can’t decide whether to remove a certain bit of duplication I’ve found, I fall back on two rules:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Remove duplication only after you see &lt;a href=&quot;https://link.jbrains.ca/qUxm1s&quot;&gt;&lt;em&gt;three&lt;/em&gt; copies&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you don’t know how to remove this particular kind of duplication, then write more tests. Either you need more examples to see the pattern, or more examples will show a different, better pattern.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I also remember two guidelines:&lt;/p&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Don’t be afraid to remove duplication by introducing a method or class or interface with a stupid name. Remember that &lt;a href=&quot;https://link.jbrains.ca/nP9Fvk&quot;&gt;you can always improve the name later&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you sense duplication, but don’t really see it, or can’t explain it to others, then &lt;a href=&quot;https://link.jbrains.ca/nP9Fvk&quot;&gt;make the surrounding names more precise&lt;/a&gt;; then maybe you will see the duplication.&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Thu, 29 Sep 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/when-should-i-remove-duplication</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/when-should-i-remove-duplication</guid>
        
        
      </item>
    
      <item>
        <title>Writing Contract Tests in Java differently</title>
        <description>&lt;p&gt;I just wanted to know whether anyone has tried nesting the concrete tests inside the abstract test like this, and if you have, then how do/did you like it?&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/1084541.js&quot;&gt; &lt;/script&gt;
</description>
        <pubDate>Sun, 17 Jul 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/writing-contract-tests-in-java-differently</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/writing-contract-tests-in-java-differently</guid>
        
        
      </item>
    
      <item>
        <title>Contract Tests: An Example</title>
        <description>&lt;p&gt;I found an example of contract tests in Arlo Belshee’s &lt;a href=&quot;https://arlobelshee.com/tag/no-mocks&quot;&gt;series of articles about mock-free testing&lt;/a&gt;. I must strongly, strongly point out that Arlo uses the term “mock” narrowly to refer to runtime- or bytecode-generated proxies that intercept interface method invocations and provide the ability to set method expectations, in the way that JMock and NMock do. He &lt;em&gt;does not&lt;/em&gt; mean the generic term “mock”, where he uses the term “test double” instead. I thank him for that.&lt;/p&gt;
&lt;p&gt;If you click &lt;a href=&quot;https://github.com/arlobelshee/ArsEditorExample/blob/master/SimulatableApi.Tests/FileSystemCanLocateFilesAndDirs.cs&quot;&gt;here&lt;/a&gt; you’ll see an almost textbook example of a contract test: that is, a test class that can run the same set of tests for two different implementations of the same interface. I would change only one thing: I’d extract the tests into an abstract superclass—something I otherwise hate to do—and pull the declaration of the method &lt;code&gt;MakeTestSubject()&lt;/code&gt; up there, leaving two subclasses, one for the real file system and one for the simulated one. “YAGNI,” you say, and I agree, but I prefer the symmetry of the abstract superclass design to the asymmetry of having one class inherit from the other. I find it easier to grok quickly.&lt;/p&gt;
&lt;p&gt;Either way, I feel good seeing contract tests out in the wild. I’m not so crazy after all.&lt;/p&gt;
</description>
        <pubDate>Thu, 07 Jul 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/contract-tests-an-example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/contract-tests-an-example</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Adding behavior with confidence</title>
        <description>&lt;h1 id=&quot;the-30-second-version&quot;&gt;The 30-second version&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Adding behavior confidently involves having fewer parts to change (low duplication), knowing which ones to change (high cohesion), ease of changing just the part you want to change (low coupling), and understanding how you’ve changed it (strong tests).&lt;/li&gt;
&lt;li&gt;Adding behavior requires breaking an existing assumption.&lt;/li&gt;
&lt;li&gt;In a well-factored design, we can easily find the one place we have made that assumption. (Otherwise, why bother refactoring?)&lt;/li&gt;
&lt;li&gt;First, make room for the new code, then add it.&lt;/li&gt;
&lt;li&gt;To make room for the new code, extract the existing code into a method whose name describes the generalisation we want to make, or the idea we want to introduce.&lt;/li&gt;
&lt;li&gt;By making room for the new code, we make that code easier to reuse by reducing its dependence on its surrounding context.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;want-to-learn-more&quot;&gt;Want to learn more?&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Visit the links in this article.&lt;/li&gt;
&lt;li&gt;Try my course: &lt;a href=&quot;//tdd.training&quot;&gt;The World’s Best Introduction to TDD&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;//book.jbrains.ca&quot;&gt;Pair with me&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;the-details&quot;&gt;The Details&lt;/h1&gt;
&lt;p&gt;We all want to add behavior to a system confidently, and I have observed that my confidence in adding behavior depends on two factors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I know where to add code.&lt;/li&gt;
&lt;li&gt;I understand the behavior of the code I am adding.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I use test-driven development as the main technique for handling the second of these two factors, but what about the first? I have uncovered a technique that I both use and teach, and I’d like to share that with you. I call this “making room for the new code”, naming it for a phrase I vaguely remember reading in one of the Grand Old XP books. (Did Kent Beck or Ron Jeffries write it? I can’t remember.) This technique helps me quickly find a reasonable first-draft place in the code base to put new code. After I have put the new code in place, and I feel confident that it does what I expect, I then use the &lt;a href=&quot;//blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;Four Elements of Simple Design&lt;/a&gt; to guide me in refactoring to improve the design.&lt;/p&gt;
&lt;h1 id=&quot;a-premise&quot;&gt;A premise&lt;/h1&gt;
&lt;p&gt;I start with the premise that &lt;strong&gt;adding behavior means breaking an assumption&lt;/strong&gt;. By this I mean that whenever we add code to a system in order to extend its behavior, we have to falsify at least one assumption we’ve previously made. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In a payroll system, in order to support a second cheque printer, we likely have to break the assumption that there is only one cheque format.&lt;/li&gt;
&lt;li&gt;In a point of sale system, in order to support separate cash and card payment reports, we likely have to break the assumption that all “we made a sale” events look the same.&lt;/li&gt;
&lt;li&gt;In a mobile phone monitoring system, in order to support billing by the second, we likely have to break the assumption that we only have to count the number of minutes a call lasted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of these seem obvious, and others less so, and it bears emphasising that the specific assumption or assumptions we break depends heavily on what we’ve built so far and the way we articulate the soon-to-be-added behavior. Even so, I conjecture that &lt;span class=&quot;highlight&quot;&gt;&lt;em&gt;for every behavior we want to add to a system, we can identify a non-empty list of assumptions that we &lt;strong&gt;need&lt;/strong&gt; to break&lt;/em&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;h1 id=&quot;the-technique&quot;&gt;The technique&lt;/h1&gt;
&lt;ol type=&quot;1&quot;&gt;
&lt;li&gt;Identify an assumption that the new behavior needs to break.&lt;/li&gt;
&lt;li&gt;Find the code that implements that assumption.&lt;/li&gt;
&lt;li&gt;Extract that code into a method whose name represents the generalisation you’re about to make.&lt;/li&gt;
&lt;li&gt;Enhance the extracted method to include the generalisation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The less duplication you have in the system, the better this works, because duplicate code makes it difficult to find all the code that implements the assumption in question. Similarly, the more appropriate the names in your system, the better this works, because unsuitable names make it difficult to know which code implements the assumption in question, as opposed to something unrelated. You’ll notice that these points relate both to the &lt;a href=&quot;//blog.jbrains.ca/permalink/the-four-elements-of-simple-design&quot;&gt;Four Elements of Simple Design&lt;/a&gt; and to the core concepts of &lt;a href=&quot;https://wiki.c2.com/?CouplingAndCohesion&quot;&gt;Coupling and Cohesion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, yes…&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
&lt;img style=&quot;width: 200px&quot; src=&quot;//images.jbrains.ca/handy-right-about-now.png&quot;&gt;&lt;/img&gt;
&lt;/div&gt;
&lt;h1 id=&quot;an-example&quot;&gt;An example&lt;/h1&gt;
&lt;p&gt;We are building a point of sale system, and we’ve just decided to implement sales tax. I live in PEI, Canada, where not only do we exclude sales tax from the price, we have two sales taxes, and we charge the second one &lt;em&gt;on top of&lt;/em&gt; the first one. For example:&lt;/p&gt;
&lt;p class=&quot;example&quot;&gt;
A $125 item that attracts both GST (the “Goods and Services” tax) and PST (provincial sales tax) costs a total of $144.38. GST at 5% costs $6.25, then PST at 10% of $131.25 (= $125 + $6.25) costs $13.13. The total is $125 + $6.25 + $13.13 = $144.38.
&lt;/p&gt;
&lt;p&gt;Notice that this example implies that GST or PST might or might not apply to a given product, so even before we identify the old assumption to break, we need to note the new assumption we’ll make: &lt;em&gt;we assume that all products attract both GST and PST&lt;/em&gt;. Our customers won’t like it, but the tax authorities will love it, and only they have the power to treat us guilty until proven innocent.&lt;/p&gt;
&lt;p&gt;Our code has a class like this in it.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/1040052.js?file=UserGestureListener.rb&quot;&gt; &lt;/script&gt;
&lt;p&gt;What do we assume now that we can’t allow ourselves to assume any longer? &lt;strong&gt;The sale total should increment by the (net) price of the item we sell.&lt;/strong&gt; By &lt;em&gt;net price&lt;/em&gt; here, I refer to the pre-tax price, because of course, until now, our system has no notion of “tax”. Fortunately, because we’ve ruthlessly removed duplication so far, computing the running total of the sale requires only this line of code. We can pretty safely apply the technique of this article right here. To do this, we extract the assumption into a new method whose name represents the generalisation we’re about to make. In this case, we don’t want to increase the sale total by the product’s &lt;em&gt;price&lt;/em&gt;, but rather by its &lt;em&gt;cost&lt;/em&gt;, which includes any additional charges beyond net price. So, we introduce a method for accumulating the scanned product’s cost.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/1040052.js?file=UserGestureListener-AddedMethodDescribingGeneralisation.rb&quot;&gt; &lt;/script&gt;
&lt;p&gt;This creates space for the new code. We test-drive the new code, and end up with this delightful monstrosity.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/1040052.js?file=UserGestureListener-Generalised.rb&quot;&gt; &lt;/script&gt;
&lt;p&gt;It looks ugly, but it works. In addition to looking ugly, this method has &lt;a href=&quot;https://wiki.c2.com/?FeatureEnvySmell&quot;&gt;Feature Envy&lt;/a&gt;. Specifically, the calculation part of &lt;code&gt;#accumulate_cost&lt;/code&gt; only talks to &lt;code&gt;product&lt;/code&gt;, and so it can move onto the class &lt;code&gt;Product&lt;/code&gt;, leaving only the accumulating left behind. You could also say that this method had two responsibilities, so I separated them, then notice the feature envy in one of them, then moved it. I can almost always take smaller steps.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/1040052.js?file=UserGestureListener-Refactored.rb&quot;&gt; &lt;/script&gt;
&lt;p&gt;Notice the &lt;a href=&quot;https://link.jbrains.ca/2u7IktO&quot;&gt;context independence&lt;/a&gt; we’ve achieved with the method &lt;code&gt;Product#cost&lt;/code&gt;. We can now refine the notion of “cost” freely without worrying about how someone will use that information. We have an easy-to-find, easy-to-extend part of the system where we can add behavior for determining which products attract which taxes, supporting multiple tax calculation policies, and even including shipping, handling and restocking fees. Now we can really add future behavior with confidence.&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Jun 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/adding-behavior-with-confidence</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/adding-behavior-with-confidence</guid>
        
        
      </item>
    
      <item>
        <title>A Model for Improving Names</title>
        <description>&lt;figure&gt;
&lt;a href=&quot;/images/a-model-for-improving-names/improving-names.png&quot;&gt;&lt;img src=&quot;/images/a-model-for-improving-names/improving-names-500px.png&quot; alt=&quot;A Model for Improving Names&quot; /&gt;&lt;/a&gt;
&lt;figcaption&gt;
A Model for Improving Names
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A model for improving the names of variables, fields, interfaces, classes and namespaces in a system. Practise this and more in my course, &lt;a href=&quot;//tdd.training&quot;&gt;The World’s Best Intro to TDD&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;(Updated August 23, 2013)&lt;/p&gt;
&lt;p&gt;Here is a great example of a &lt;em&gt;structurally accurate&lt;/em&gt; name:&lt;/p&gt;
&lt;figure&gt;
&lt;a href=&quot;https://geek-and-poke.com/geekandpoke/2013/8/20/naming-is-key&quot;&gt;&lt;img src=&quot;//static.squarespace.com/static/518f5d62e4b075248d6a3f90/t/521456efe4b0436556b1630d/1377064694748/good-names4.jpg&quot; alt=&quot;Geek and Poke&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;You can find the original comic (and more) at &lt;a href=&quot;//geek-and-poke.com/geekandpoke/2013/8/20/naming-is-key&quot;&gt;Geek and Poke&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The classic name for this kind of class ends in &lt;code&gt;Util&lt;/code&gt;. Smalltalk browsers label these classes as a code smell. I have used the intention-revealing name &lt;code&gt;JunkDrawer&lt;/code&gt; for classes like these. Once, while working with a team near Philadelphia, we had an Eclipse project like this, which we first called “Dumping Ground”, but which we eventually renamed to “New Jersey”.&lt;/p&gt;
&lt;p&gt;(Updated August 29, 2013)&lt;/p&gt;
&lt;p&gt;It seems that Geek and Poke have tapped directly into my brain. I will have to use this name in my projects.&lt;/p&gt;
&lt;figure&gt;
&lt;a href=&quot;//link.jbrains.ca/18mZk94&quot;&gt;&lt;img src=&quot;//static.squarespace.com/static/518f5d62e4b075248d6a3f90/t/521bc806e4b08ade07864b34/1377552402666/area51.jpg&quot; alt=&quot;Geek and Poke&quot; /&gt;&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;You can find the original comic (and more) at &lt;a href=&quot;//link.jbrains.ca/18mZk94&quot;&gt;Geek and Poke&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Arlo Belshee, &lt;a href=&quot;https://arlobelshee.com/tag/naming-is-a-process/&quot;&gt;“Naming is a Process”&lt;/a&gt;. Another fantastic series of articles that describes a similar approach to names: improving names over time, rather than feeling stress to “get them right” “the first time”.&lt;/p&gt;
&lt;p&gt;Katrina Owen, &lt;a href=&quot;//www.sitepoint.com/whats-in-a-name-anti-patterns-to-a-hard-problem/&quot;&gt;“What’s In a Name? Anti-Patterns to a Hard Problem”&lt;/a&gt;. An example along the path from nonsense through structural naming towards revealing intent, meaning, or purpose.&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Jun 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/a-model-for-improving-names</guid>
        
        
        <category>Improving Names</category>
        
      </item>
    
      <item>
        <title>The Continuum of Names: an example</title>
        <description>&lt;p&gt;I found someone trying to work on improving names in their code, and &lt;a href=&quot;https://gist.github.com/986928&quot;&gt;gave them a little advice&lt;/a&gt;. It gives a reasonable example of some of the things I think about when naming.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;UPDATE: 2012-11-29&lt;/em&gt; I wrote more about this in &lt;a href=&quot;/2011/06/15/a-model-for-improving-names/&quot;&gt;A Model for Improving Names&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Fri, 27 May 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/the-continuum-of-names-an-example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/the-continuum-of-names-an-example</guid>
        
        
        <category>Improving Names</category>
        
      </item>
    
      <item>
        <title>Code Rejects Inheritance-Based Reuse: An Example</title>
        <description>&lt;p&gt;We’ve read this before: don’t reuse code by subclassing. Instead, compose objects into a loose network that share responsibility for the system’s behavior. While practising, working through Growing Object-Oriented Systems, I reached the point where Steve and Nat started writing microtests, and decided to stray from the text and try it out on my own. I reached the stage where the first two system tests pass, but in the process, I introduced much cyclic dependency and duplication, particularly related to sending and parsing chat messages. In preparing to address this problem, I noticed some duplication in how the &lt;em&gt;auction&lt;/em&gt; handles its incoming chats: sometimes it updated the UI, and sometimes it didn’t. I figured I’d turn those into two chat message handlers, separating the UI behavior from the non-UI behavior, and in so doing, introduced some temporary duplication.&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.auction.test;

public class Main implements MessageListener {
    // ...
    private void joinAuction(final XMPPConnection connection, String itemId)
            throws XMPPException {

        disconnectWhenUiCloses(connection);
        final Chat chat = connection.getChatManager().createChat(
                auctionId(itemId, connection), new MessageListener() {
                    // SMELL This nested class makes cyclic dependencies too
                    // easy
                    @Override
                    public void processMessage(Chat chat, Message message) {
                        // REFACTOR Replace conditional with polymorphism in
                        // each

                        // SMELL This duplicates code in Main&amp;#39;s message
                        // listener,
                        // which probably means an abstraction in the middle is
                        // missing.
                        // REFACTOR? MessageListener parses messages and fires
                        // auction events; AuctionEventListener updates UI or
                        // sends chat message
                        final Object event = Messages.parse(message);
                        if (event instanceof BiddingState) {
                            BiddingState biddingState = (BiddingState) event;
                            if (!Main.SNIPER_XMPP_ID.equals(biddingState
                                    .getBidderName())) {
                                counterBid(chat);
                            }
                        }
                    }
                });

        chat.addMessageListener(this);

        this.dontGcMeBro = chat;

        chat.sendMessage(Messages.joinAuction());
    }
    
    //...
    
    @Override
    public void processMessage(Chat chat, Message message) {
        // SMELL This duplicates code in joinAuction()&amp;#39;s message listener,
        // which probably means an abstraction in the middle is
        // missing.
        // REFACTOR? MessageListener parses messages and fires
        // auction events; AuctionEventListener updates UI or
        // sends chat message
        Object event = Messages.parse(message);
        if (event instanceof BiddingState) {
            BiddingState biddingState = (BiddingState) event;
            if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                signalSniperIsBidding();
            }
        } else {
            signalAuctionClosed();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
You can probably see a straightforward way to start removing this duplication. To illustrate it, look at the following code snippet.
&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.auction.test;

public class Main {
    public static final class BidsForSniperMessageListener implements
            MessageListener {

        private Main main;

        public BidsForSniperMessageListener(Main main) {
            this.main = main;
        }

        // SMELL This nested class makes cyclic dependencies too
        // easy
        @Override
        public void processMessage(Chat chat, Message message) {
            // REFACTOR Replace conditional with polymorphism in
            // each

            // SMELL This duplicates code in Main&amp;#39;s message
            // listener,
            // which probably means an abstraction in the middle is
            // missing.
            // REFACTOR? MessageListener parses messages and fires
            // auction events; AuctionEventListener updates UI or
            // sends chat message
            final Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                    main.counterBid(chat);
                }
            }
        }
    }

    public static class UpdatesMainWindowMessageListener implements
            MessageListener {
        private final Main main;

        public UpdatesMainWindowMessageListener(Main main) {
            this.main = main;
        }

        @Override
        public void processMessage(Chat chat, Message message) {
            // SMELL This duplicates code in joinAuction()&amp;#39;s message listener,
            // which probably means an abstraction in the middle is
            // missing.
            // REFACTOR? MessageListener parses messages and fires
            // auction events; AuctionEventListener updates UI or
            // sends chat message
            Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                    main.signalSniperIsBidding();
                }
            } else {
                main.signalAuctionClosed();
            }
        }
    }

    //...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
So we have two classes with a common field, a common method signature, and similar method bodies. Extract Superclass seems logical, even though I can’t think of a decent name for this class so far. No worry: it will come to me.
&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.auction.test;

public class Main {
    public static class FooMessageListener implements MessageListener {
        @Override
        public void processMessage(Chat chat, Message message) {
        }
    }

    public static final class BidsForSniperMessageListener extends
            FooMessageListener {
        
        private final Main main;

        public BidsForSniperMessageListener(Main main) {
            this.main = main;
        }

        @Override
        public void processMessage(Chat chat, Message message) {
            final Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                    main.counterBid(chat);
                }
            }
        }
    }

    public static class UpdatesMainWindowMessageListener extends
            FooMessageListener {

        private final Main main;

        public UpdatesMainWindowMessageListener(Main main) {
            this.main = main;
        }

        @Override
        public void processMessage(Chat chat, Message message) {
            Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                    main.signalSniperIsBidding();
                }
            } else {
                main.signalAuctionClosed();
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Next, we have to extract the parts that differ from the parts the match each other. I did that by introducing new methods.
&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.auction.test;

public class Main {
    public static class FooMessageListener implements MessageListener {
        @Override
        public void processMessage(Chat chat, Message message) {
        }
    }

    public static final class BidsForSniperMessageListener extends
            FooMessageListener {
        
        private final Main main;

        public BidsForSniperMessageListener(Main main) {
            this.main = main;
        }

        // SMELL This nested class makes cyclic dependencies too
        // easy
        @Override
        public void processMessage(Chat chat, Message message) {
            final Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                handleBiddingStateEvent(chat, biddingState);
            }
        }

        private void handleBiddingStateEvent(Chat chat,
                BiddingState biddingState) {
            if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                main.counterBid(chat);
            }
        }
    }

    public static class UpdatesMainWindowMessageListener extends
            FooMessageListener {

        private final Main main;

        public UpdatesMainWindowMessageListener(Main main) {
            this.main = main;
        }

        @Override
        public void processMessage(Chat chat, Message message) {
            Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                handleBiddingStateEvent(biddingState);
            } else {
                handleAllOtherEvents();
            }
        }

        private void handleAllOtherEvents() {
            main.signalAuctionClosed();
        }

        private void handleBiddingStateEvent(BiddingState biddingState) {
            if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                main.signalSniperIsBidding();
            }
        }
    }
    //...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Next, we make &lt;code&gt;processMessage()&lt;/code&gt; identical in both classes, so as to pull it up into &lt;code&gt;FooMessageListener&lt;/code&gt;. And here, we find our first warning sign about this refactoring. The signatures of &lt;code&gt;handleBiddingStateEvent()&lt;/code&gt; don’t match:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;BidsForSniperMessageListener.handleBiddingStateEvent(Chat, BiddingState)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UpdatesMainWindowMessageListener.handleBiddingStateEvent(BiddingState)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In order to find out whether this will become a problem, I have to add &lt;code&gt;Chat&lt;/code&gt; to the parameter list for &lt;code&gt;UpdatesMainWindowMessageListener&lt;/code&gt;’s implementation of the method, at least for now. I imagine I could do something more clever, but I’m not sure that introducing a closure over a &lt;code&gt;Chat&lt;/code&gt; object would simplify matters. I can put that on my “to try” list for now. In the meantime, I add the &lt;code&gt;Chat&lt;/code&gt; parameter. &lt;a href=&quot;https://bit.ly/mnNv95&quot; target=&quot;_blank&quot;&gt;See the diff.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now to turn similar &lt;code&gt;processMessage()&lt;/code&gt; implementations into identical ones, I introduced an empty method. This is another warning sign, since I can’t envision a “default” UI update. Still, I reserve judgment until I have more evidence, and introduce the necessary changes. &lt;a href=&quot;https://bit.ly/jjJQJI&quot; target=&quot;_blank&quot;&gt;See the diff.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now that &lt;code&gt;processMessage()&lt;/code&gt; looks identical in both subclasses, we can pull it up into &lt;code&gt;FooMessageListener&lt;/code&gt;, for which we still don’t have a good name. Either &lt;a href=&quot;https://bit.ly/mHVAaD&quot; target=&quot;_blank&quot;&gt;see the diff&lt;/a&gt; or look at the final result below.
&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.auction.test;

public class Main {
    public static abstract class FooMessageListener implements MessageListener {
        @Override
        public void processMessage(Chat chat, Message message) {
            final Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                handleBiddingStateEvent(chat, biddingState);
            } else {
                handleAllOtherEvents();
            }
        }

        protected abstract void handleAllOtherEvents();

        protected abstract void handleBiddingStateEvent(Chat chat,
                BiddingState biddingState);
    }

    public static final class BidsForSniperMessageListener extends
            FooMessageListener {

        private final Main main;

        public BidsForSniperMessageListener(Main main) {
            this.main = main;
        }

        @Override
        protected void handleAllOtherEvents() {
            // I don&amp;#39;t need to do anything here
        }

        @Override
        protected void handleBiddingStateEvent(Chat chat,
                BiddingState biddingState) {
            if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                main.counterBid(chat);
            }
        }
    }

    public static class UpdatesMainWindowMessageListener extends
            FooMessageListener {

        private final Main main;

        public UpdatesMainWindowMessageListener(Main main) {
            this.main = main;
        }

        @Override
        protected void handleAllOtherEvents() {
            main.signalAuctionClosed();
        }

        @Override
        protected void handleBiddingStateEvent(
                @SuppressWarnings(&amp;quot;unused&amp;quot;) Chat chat, BiddingState biddingState) {
            if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                main.signalSniperIsBidding();
            }
        }
    }
    //...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Now that I look at this last version of &lt;code&gt;Main&lt;/code&gt;, I see the value in having attempted this refactoring. It clarifies quite well the specific reasons why I won’t let inheritance play a long-term role in this part of the design. Specifically, look at the little problems with this design.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I still can’t think of a good name for &lt;code&gt;FooMessageListener&lt;/code&gt;, although maybe you’re screaming one at me as you read. (Sorry; I can’t hear you.)
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BidsForSniperMessageListener.handleAllOtherEvents()&lt;/code&gt; doesn’t need to do anything, which might or might not be a problem, but often points to the Refused Bequest smell.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UpdatesMainWindowMessageListener.handleBiddingStateEvent()&lt;/code&gt; doesn’t need its &lt;code&gt;chat&lt;/code&gt; parameter.
&lt;/li&gt;
&lt;li&gt;
Both subclasses need a reference back to &lt;code&gt;Main&lt;/code&gt;, but the superclass &lt;code&gt;FooMessageListener&lt;/code&gt; doesn’t need it. Of course, that says more about &lt;code&gt;Main&lt;/code&gt; in general than the &lt;code&gt;FooMessageListener&lt;/code&gt; hierarchy: &lt;code&gt;Main&lt;/code&gt; violates the Single Responsibility Principle in a variety of delightful ways. That’s why we’re here.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So let me talk this through: we have subclasses of &lt;code&gt;FooMessageListener&lt;/code&gt; that respond to the same logical stimuli, but different subclasses need different data and sometimes a subclasses doesn’t need to respond to the stimuli at all. &lt;strong&gt;That sounds an awful lot like an event mechanism to me.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
And if you look ahead in Steve and Nat’s book, that’s not surprising.
&lt;/p&gt;
&lt;p&gt;
So how do we get from here to there? I plan to attack it this way:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Make &lt;code&gt;FooMessageListener&lt;/code&gt; an event source for this new type of event, which I’ll tentatively call an &lt;code&gt;AuctionEvent&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
Turn the subclasses into &lt;code&gt;AuctionEventListener&lt;/code&gt;s.
&lt;/li&gt;
&lt;li&gt;
Inline stuff back into place.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
You can follow the detailed changes on &lt;a href=&quot;https://bit.ly/kdotl2&quot; target=&quot;_blank&quot;&gt;this branch&lt;/a&gt; starting with &lt;a href=&quot;https://bit.ly/mHVAaD&quot; target=&quot;_blank&quot;&gt;this commit&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
By the end of this session, I ended up with a new Auction Event concept, which has started separating the “chat message” concept from the “auction changed” event. It does, however, lead to other questions, which I’ve highlighted with &lt;code&gt;SMELL&lt;/code&gt; and &lt;code&gt;REFACTOR&lt;/code&gt; comments, so look for them. For now, I feel good that, while introducing a hierarchy had its problems, it helped me see how specifically to eliminate it. I trusted the mechanics, and it helped me see where to go next. I know I need to introduce an “auction closed” event and perhaps need to introduce an &lt;code&gt;AuctionEvent&lt;/code&gt; object to eliminate the need for type checking in &lt;code&gt;AuctionEventSourceMessageListener&lt;/code&gt;. We’ll go there next time, but in the meantime, peruse the current state of the code.
&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;package ca.jbrains.auction.test;

public class Main {
    public interface AuctionEventListener {
        void handleNewBiddingState(BiddingState biddingState);

        void handleGenericEvent(Object object);
    }

    public static class AuctionEventSourceMessageListener implements
            MessageListener {

        private final List&amp;lt;AuctionEventListener&amp;gt; listeners;

        public AuctionEventSourceMessageListener() {
            this.listeners = new ArrayList&amp;lt;AuctionEventListener&amp;gt;();
        }

        public void addListener(AuctionEventListener listener) {
            listeners.add(listener);
        }

        @Override
        public void processMessage(Chat chat, Message message) {
            // SMELL Duplicated loops
            final Object event = Messages.parse(message);
            if (event instanceof BiddingState) {
                BiddingState biddingState = (BiddingState) event;
                for (AuctionEventListener each : listeners) {
                    each.handleNewBiddingState(biddingState);
                }
            } else {
                for (AuctionEventListener each : listeners) {
                    each.handleGenericEvent(event);
                }
            }
        }
    }
    //...
    private void joinAuction(final XMPPConnection connection, String itemId)
            throws XMPPException {

        disconnectWhenUiCloses(connection);

        final AuctionEventSourceMessageListener auctionEventSource = new AuctionEventSourceMessageListener();

        final Chat chat = connection.getChatManager().createChat(
                auctionId(itemId, connection), auctionEventSource);

        // SMELL? Programming by accident that I can&amp;#39;t add these listeners in
        // the constructor of the Auction Event Source?
        auctionEventSource.addListener(new AuctionEventListener() {
            @Override
            public void handleNewBiddingState(BiddingState biddingState) {
                // REFACTOR? Should &amp;quot;sniper now losing&amp;quot; be an event?
                if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                    counterBid(chat);
                }
            }

            @Override
            public void handleGenericEvent(Object object) {
                // I can ignore this
            }
        });

        auctionEventSource.addListener(new AuctionEventListener() {
            @Override
            public void handleNewBiddingState(BiddingState biddingState) {
                // REFACTOR? Should &amp;quot;sniper now losing&amp;quot; be an event?
                if (!Main.SNIPER_XMPP_ID.equals(biddingState.getBidderName())) {
                    signalSniperIsBidding();
                }
            }

            @Override
            public void handleGenericEvent(Object object) {
                // REFACTOR Introduce an &amp;quot;auction closed&amp;quot; event
                signalAuctionClosed();
            }
        });

        this.dontGcMeBro = chat;

        chat.sendMessage(Messages.joinAuction());
    }
    //...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
If you prefer, &lt;a href=&quot;https://bit.ly/iNyNbc&quot; target=&quot;_blank&quot;&gt;look at the changes&lt;/a&gt; in moving from &lt;code&gt;MessageListener&lt;/code&gt;s to &lt;code&gt;AuctionEventListener&lt;/code&gt;s.
&lt;/p&gt;
&lt;p&gt;
I hope I’ve shown how a code base can reject an attempt to reuse code by inheritance, prefering instead, in this case, composition implemented as an event chain.
&lt;/p&gt;
</description>
        <pubDate>Mon, 02 May 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/code-rejects-inheritance-based-reuse-an-example</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/code-rejects-inheritance-based-reuse-an-example</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam): No conflict with GOOS</title>
        <description>&lt;p&gt;&lt;em&gt;I’ve taken this verbatim from a thread in the Google group for Steve Freeman and Nat Pryce’s excellent work, Growing Object-Oriented Systems Guided by Tests. As I’ve said before, they’ve written the book I wish I’d written. I quote Rick Pingry below.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My partner and I were just looking at a video you made a while back about integration tests being snake oil. The GOOS book of course talks about Acceptance Tests, but perhaps you are making a differentiation between acceptance tests and integration tests. I bring it up in this thread because I think it is relevant.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Short version: Don’t use end-to-end tests to avoid flaws in the basic correctness of your system.&lt;/p&gt;
&lt;p&gt;The crux of the problem: The Average Person™ conflates “Acceptance test” (help the Customer feel good that the feature is present) with “System test” (help the Programmer feel good that the system components work together correctly) because they &lt;em&gt;tend&lt;/em&gt; both to be end-to-end tests. As a result, the Average Person doesn’t write enough microtests.&lt;/p&gt;
&lt;p&gt;GOOS uses Acceptance Tests to guide programming and help Programmers know when they’ve built enough stuff. Because they choose to implement those tests in Java, the Average Reader™ might interpret those tests as System Tests, and believe that they serve the purpose of making sure the whole system works. Even when GOOS &lt;em&gt;does&lt;/em&gt; use them as System Tests, the book also shows many, many microtests, thereby avoiding the logic error that the Average Person™ makes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In there you take the approach that you should mock ALL collaborators. In a bit of code we wrote recently, we did that very thing, but find that making changes to how the thing works is hard. Refactoring becomes harder. (I wrote about this before and got lots of great advice from you guys, but I think I understand better about what is going on now so I can speak a little more intelligently about it). The tests become glue that makes any kind of change to HOW a class is implemented difficult if you ever want to extract an internal. The GOOS book and this thread talk about a difference between peers and internals, and I get the impression that you should mock the peers and not mock the internals. I am not so sure now after hearing your talk about that. Am I missing something?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;No. I agree about using test doubles for peers, not internals. I simply use the painful pressure from trying to use test doubles for all collaborators to help me classify them as peers or internals. Sometimes I guess well about that classification as a shortcut, but when I don’t guess well, I can always take the long route.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you are mocking out every collaboration between every class in your system, how do you refactor anything without breaking tests? Are you supposed to be able to refactor without breaking tests? Could you provide an example of how you do that?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I tend more often to throw away tests than break them. If changing a client leads to changing a peer interface, then I switch to revising the contract tests for that interface. Sometimes this means throwing tests away, because sometimes this means throwing an interface away.&lt;/p&gt;
&lt;p&gt;I’m afraid I have no example to show you, because contrived examples don’t demonstrate the point adequately, and I don’t own the IP rights to the real-life examples I’ve used.&lt;/p&gt;
</description>
        <pubDate>Mon, 25 Apr 2011 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/no-conflict-with-goos</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/no-conflict-with-goos</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Use Your Singletons Wisely: Ten Years Later</title>
        <description>&lt;p&gt;
I recently received this comment at IBM DeveloperWorks about my now-very-old article, &lt;a href=&quot;/assets/use-your-singletons-wisely-original.pdf&quot;&gt;Use your singletons wisely&lt;/a&gt;. I really like knowing that people continue to read that article, since it was the first I published online somewhere other than my own web site.
&lt;/p&gt;
&lt;p&gt;
Brent Arias, also known as &lt;strong&gt;mystagogue&lt;/strong&gt;, wrote:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
There is such a thing as singletons, in some languages, that can be “property” dependency injected, which essentially nullifies the suggested reason (viz. testability) for avoiding them (I do this with C#). Also, Liskov Substitution is not violated by singletons, because Liskov Substitution does not apply to constructors (which in part is why there is no such thing as “virtual constructors”). Finally, dependency injection is not without its own hazards. For example, many interim classes are forced now to take dependencies they don’t need, simply to pass them on to child classes which do need them. As such, dependency injection actually increases coupling between classes!!!
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I’d like to thank Brent for his comment. Of course, I didn’t know then what I know now, so I didn’t mention the points that Brent raised in his recent comment. I’d like to address those points now.
&lt;/p&gt;
&lt;h1&gt;
The Testability Problem
&lt;/h1&gt;
&lt;p&gt;
First, Brent says that since he can inject a dependency through a property in C#, there is no testability problem. I disagreed with this in JUnit Recipes, recipes 14.3 and 14.4, which cover testing singletons and their clients. I agree that being able to inject the singleton instance makes run-time substitution in the tests possible, it defeats the purpose of designing the class as a singleton. Yes, you can resort to making the &lt;code&gt;setInstance()&lt;/code&gt; method or &lt;code&gt;Instance&lt;/code&gt; property writable only in the tests, but this serves only to complicate the design, rather than simplify it, and so I’d typically prefer to use this as an intermediate step towards a simpler design.
&lt;/p&gt;
&lt;h1&gt;
About LSP…
&lt;/h1&gt;
&lt;p&gt;
Next, Brian says that since the Liskov Substitution Principle does not apply to constructors, then a singleton-based design does not violate the principle. I had never thought about this before, so I researched the topic a little. The principle states that any property provable about a type must also be true of any subtype of that type. I suppose that, since constructors belong to the type class and not objects of the type, then Brent is correct: LSP does not apply to constructors. Even so, I had written this:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
[…] any change in how the supplier class is instantiated ripples into the client class. This violates the Liskov Substitution Principle, which states that you should allow any application the freedom to tell the client class to collaborate with any subclass of the supplier.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I had written about the consequences of LSP, and not the principle itself, in rather a sloppy fashion. While one can subclass a singleton in a way that respects LSP, in order to use that subclass, one would have to make a choice between two poor alternatives: change clients to invoke &lt;code&gt;Subclass.getInstance()&lt;/code&gt; instead of &lt;code&gt;Superclass.getInstance()&lt;/code&gt; or change &lt;code&gt;Superclass.getInstance()&lt;/code&gt; to become a proper Factory (in the Design Patterns sense) for the &lt;code&gt;Superclass&lt;/code&gt; hierarchy. &lt;strong&gt;Choosing the first option violates the benefit of LSP&lt;/strong&gt;, if not LSP itself: when you violate LSP you make changes that ripple out into your client, and so to avoid affecting your client, among other things, respect LSP. Choosing the second option leads you to a Singleton/Factory hybrid in which &lt;code&gt;Superclass&lt;/code&gt; knows about &lt;code&gt;Subclass&lt;/code&gt;, violating even more fundamental design principles, like Open/Closed. I don’t like either choice. &lt;strong&gt;I wish I had written this instead of what I wrote in the original article.&lt;/strong&gt;
&lt;/p&gt;
&lt;h1&gt;
I Just Don’t Have This Problem
&lt;/h1&gt;
&lt;p&gt;
Finally, Brent says that, with dependency injection, “many interim classes are forced now to take dependencies they don’t need, simply to pass them on to child classes which do need them”. I agree with Brent, but strongly point out that dependency injection uncovers symptoms like these of deeper design problems, rather than creating these design problems in the first place. Unfortunately, I don’t have a concrete example to offer you, so I have to resort to one of those hopelessly abstract examples. I hope you’ll bear with me. If I find a better example, I’ll use it.
&lt;/p&gt;
&lt;p&gt;
Consider three classes, unimaginatively named &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt;. In our design, &lt;code&gt;A&lt;/code&gt; uses &lt;code&gt;B&lt;/code&gt;, and then &lt;code&gt;B&lt;/code&gt; uses &lt;code&gt;C&lt;/code&gt;. Since this design doesn’t yet inject dependencies, we have something like this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class A {
  public A() {
    this.b = new B();
  }
}

class B {
  public B() {
    this.c = new C();
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;So far, so good.&lt;/strong&gt; (Well, not really, but good enough for now.) Now we want to switch to a dependency injection-based design to make it collaborators more pluggable. (I won’t bother with the reasons here; in a purely abstract example, there are no reasons.) This means that I first inject &lt;code&gt;C&lt;/code&gt; into &lt;code&gt;B&lt;/code&gt; through its constructor:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class B {
  public B(C c) {
    this.c = c;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Now &lt;code&gt;A&lt;/code&gt; needs to give &lt;code&gt;B&lt;/code&gt; a &lt;code&gt;C&lt;/code&gt;, but where does the &lt;code&gt;C&lt;/code&gt; come from?
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class A {
  public A() {
    this.b = new B(new C());
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
The Problem, as Brent Describes It
&lt;/h2&gt;
&lt;p&gt;
This doesn’t look right, so we &lt;em&gt;could&lt;/em&gt; decide to make the client give &lt;code&gt;A&lt;/code&gt; a &lt;code&gt;C&lt;/code&gt;, so that &lt;code&gt;A&lt;/code&gt; can pass that on to &lt;code&gt;B&lt;/code&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class A {
  public A(C c) {
    this.b = new B(c);
  }
}

class Client {
  someMethod() {
    A a = new A(new C());
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
If Injecting Worked Once…
&lt;/h2&gt;
&lt;p&gt;
But now, of course, we have the case where &lt;code&gt;A&lt;/code&gt; knows about &lt;code&gt;C&lt;/code&gt; even though &lt;code&gt;A&lt;/code&gt; doesn’t use it directly. If I understand Brent correctly, then this is his objection. One problem: why does &lt;code&gt;A&lt;/code&gt; create the &lt;code&gt;B&lt;/code&gt; directly? Why not inject that, too?
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class A {
  public A(B b) {
    this.b = b;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Now the client, which was already creating a &lt;code&gt;C&lt;/code&gt;, simply creates a &lt;code&gt;B&lt;/code&gt;, too:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Client {
  someMethod() {
    A a = new A(new B(new C()));
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
This way, &lt;code&gt;A&lt;/code&gt; need not know anything about &lt;code&gt;C&lt;/code&gt;, although if &lt;code&gt;A&lt;/code&gt; eventually does need to use &lt;code&gt;C&lt;/code&gt; directly, it can easily do so:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Client {
  someMethod() {
    C c = new C();
    A a = new A(new B(c), c);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
This duplication, however, leads me to ask a few questions:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Do &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; use &lt;code&gt;C&lt;/code&gt; differently?&lt;/strong&gt; If they do, then maybe I should split &lt;code&gt;C&lt;/code&gt; into two classes, &lt;code&gt;D&lt;/code&gt; and &lt;code&gt;E&lt;/code&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Client {
  someMethod() {
    A a = new A(new B(new D()), new E());
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Do &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; use &lt;code&gt;C&lt;/code&gt; for a similar reason?&lt;/strong&gt; If they do, then maybe &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; duplicate some effort. Since &lt;code&gt;A&lt;/code&gt; is &lt;code&gt;B&lt;/code&gt;’s client, I would probably move that behavior from &lt;code&gt;B&lt;/code&gt; to &lt;code&gt;A&lt;/code&gt;, so that &lt;code&gt;B&lt;/code&gt; no longer uses &lt;code&gt;C&lt;/code&gt; at all:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Client {
  someMethod() {
    A a = new A(new B(), new C());
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Is there some combination of both? If so, then likely I need to do both. Fortunately, that’s just another formulation of the first possibility.
&lt;/p&gt;
&lt;p&gt;
There might be more questions, but that will do. While injecting the dependency appeared to make the classes more tightly coupled, it simply &lt;strong&gt;revealed the coupling that already existed&lt;/strong&gt;. &lt;code&gt;A&lt;/code&gt; was already tightly coupled to &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; to &lt;code&gt;C&lt;/code&gt;. When we tried to inject the dependency, we made that coupling more explicit and easier to remove.
&lt;/p&gt;
&lt;p&gt;
So thanks, Brent, for your comment, as it gave me an opportunity to follow up on my thinking about Singletons and design. I hope this response helps you understand why I don’t worry about the issues you brought up. Thanks, as well, for pointing out the error in my exposition about the Liskov Substitution Principle. I freely admit that, as a new face at the time, I mostly wanted to sound smart.
&lt;/p&gt;
</description>
        <pubDate>Tue, 01 Mar 2011 02:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/use-your-singletons-wisely-ten-years-later</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/use-your-singletons-wisely-ten-years-later</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>Injecting dependencies doesn&apos;t have to hurt</title>
        <description>&lt;p&gt;I have noticed a recent swell of comments about the pain of dependency injection, and if this has caused you problems on your project, then I think I can help you by offering a few simple guidelines and a single goal for injecting dependencies.&lt;/p&gt;
&lt;h2&gt;
The guidelines
&lt;/h2&gt;
&lt;p&gt;
I have formulated these as &lt;a href=&quot;https://bit.ly/sYj5Y&quot; target=&quot;_blank&quot;&gt;Novice or Advanced Beginner&lt;/a&gt; rules, and so I have worded them more strongly than I tend to word my advice.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
When in doubt, inject each dependency directly into the method that requires it.
&lt;/li&gt;
&lt;li&gt;
Only when you inject the same dependency into multiple methods of the same class, move the parameter into the constructor.
&lt;/li&gt;
&lt;li&gt;
Do not use so-called “setter injection” except as an intermediate step in a refactoring aimed at injecting the dependency into a method or the constructor.
&lt;/li&gt;
&lt;li&gt;
Stop using the Service Locator pattern, and instead inject the service into the client.
&lt;/li&gt;
&lt;li&gt;
Stop instantiating collaborating services (in the &lt;a href=&quot;https://bit.ly/gyLuWK&quot; target=&quot;_blank&quot;&gt;Domain-Driven Design sense&lt;/a&gt;), and instead inject those services into the client.
&lt;/li&gt;
&lt;li&gt;
When a constructor parameter list becomes uncomfortably long, split the class so that the new classes’ constructor parameter lists don’t overlap.
&lt;/li&gt;
&lt;li&gt;
If you notice a class using the same dependency through two different object graph routes, split the class so that the new classes receive the dependency directly in their constructors.
&lt;/li&gt;
&lt;li&gt;
If you notice a class using groups of dependencies at different times, split the class so that the new classes only use each cohesive group of dependencies.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All these guidelines have their roots in “remove duplication” and “fix bad names”, two of the &lt;a href=&quot;https://bit.ly/g9P6Jw&quot; target=&quot;_blank&quot;&gt;four elements of simple design&lt;/a&gt;.
&lt;/p&gt;
&lt;h2&gt;
So why inject dependencies at all?
&lt;/h2&gt;
&lt;p&gt;
Some people inject dependencies in order to stub, mock or spy on a method for testing. I used to use that as a primary motivation, but over the years that motivation has evolved into something more widely useful. I inject dependencies for one reason: to move the things that change in the direction of the client and the things that don’t in the direction of the supplier. Or, if you prefer, “abstractions in code, details in data”. Or, if you prefer, to avoid abstractions depending on details. Any of those will do.
&lt;/p&gt;
&lt;h2&gt;
You don’t buy it?
&lt;/h2&gt;
&lt;p&gt;
No problem. I’ll write more articles in this space showing examples of each of the guidelines, and you’ll have plenty of opportunity to share your opinions about them.
&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Dec 2010 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/injecting-dependencies-doesnt-have-to-hurt</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/injecting-dependencies-doesnt-have-to-hurt</guid>
        
        
        <category>Dependency Inversion Principle (DIP)</category>
        
      </item>
    
      <item>
        <title>JMock v. Mockito, but not to the death</title>
        <description>&lt;p class=&quot;update&quot;&gt;
Although I originally wrote this to describe how/when I use JMock compared to Mockito, you can easily read this as an article comparing the use of mocks (expectations) to the use of spies. JMock operates by default in “expectation” mode, while Mockito operates by default in “spy” mode. In short: expectations and spies have exactly the same expressive power and so I use both in different contexts.
&lt;/p&gt;
&lt;p&gt;I grew up using EasyMock, but near the end of the first draft of JUnit Recipes, I wrote this:&lt;/p&gt;
&lt;blockquote&gt;
“In the time between writing this essay and sending the book to be printed, a new dynamic proxy-based mock objects package has appeared on the scene, called jMock (www.jmock.org). It picks up where EasyMock left off, as the EasyMock project went through a temporary lull in activity, between October 2003 and May 2004. Being so new, we do not have any experience using it, and so we cannot say much about it, but it does look promising and bears a look. If you have used EasyMock, then it is worth experimenting with jMock to see the difference. You may find you prefer jMock’s approach to that of EasyMock.”
&lt;/blockquote&gt;
&lt;p&gt;Since 2004 I have used JMock almost exclusively to drive my designs in Java. I even like the strange-looking JMock 2 syntax which, I know, puts me in the minority. In the last two years, other test double libraries have gained mindshare, among which Mockito has become quite prominent. While I can’t give you a feature-by-feature comparison, I can tell you this:&lt;/p&gt;
&lt;p&gt;When I want to rescue legacy code, I reach for Mockito. When I want to design for new features, I reach for JMock.&lt;/p&gt;
&lt;p&gt;Different central assumptions of JMock and Mockito make each one better at its respective task. By default, JMock assumes that a test double (a “mock”) expects clients not to invoke anything at any time. If you want to relax that assumption, then you have to add a stub. On the other hand, Mockito assumes that a test double (sadly, also a “mock”) allows clients to invoke anything at any time. If you want to strengthen that assumption, then you have to verify a method invocation. This makes all the difference.&lt;/p&gt;
&lt;p&gt;When I work with legacy code, I mostly write learning tests to discover how different parts of that legacy code behaves. Usually legacy code has obscene and overwhelming levels of interdependency, and Mockito helps me manage that, by allowing me to worry about one crazy dependency at a time.&lt;/p&gt;
&lt;p&gt;When I design for new features, I mostly write design tests that describe the new behavior I want to implement. With the nice green field of a new interface, I need JMock to encourage me to clarify the interaction I need. Whenever my production code attempts to use a collaborator, JMock effectively reminds me to ensure that I want that interaction. Most importantly, JMock stops me from introducing dependencies that I don’t need.&lt;/p&gt;
&lt;p&gt;I really like Fred Brooks’ use of the terms &lt;em&gt;essential complexity&lt;/em&gt; and &lt;em&gt;accidental complexity&lt;/em&gt;. Briefly, a code base’s &lt;em&gt;essential&lt;/em&gt; complexity reflects the complexity of the problem. Automating tax audits will result in high essential complexity. A code base’s &lt;em&gt;accidental complexity&lt;/em&gt; reflects the complexity we programmers add because we don’t design simply. In short, if it isn’t essential complexity, then it’s accidental complexity. Our job as designers includes minimising accidental complexity.&lt;/p&gt;
&lt;p&gt;Mockito helps me tolerate high accidental complexity while I work to reduce it.&lt;/p&gt;
&lt;p&gt;JMock tries its best to stop me from introducing accidental complexity.&lt;/p&gt;
&lt;p&gt;That explains why I use JMock when designing for new features and why I’ll recommend using Mockito for rescuing legacy code.&lt;/p&gt;
</description>
        <pubDate>Tue, 05 Oct 2010 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/jmock-v-mockito-but-not-to-the-death</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/jmock-v-mockito-but-not-to-the-death</guid>
        
        
      </item>
    
      <item>
        <title>Stub your data access layer; it won&apos;t hurt</title>
        <description>&lt;p&gt;I came across this question on the &lt;code&gt;testdrivendevelopment&lt;/code&gt; Yahoo! group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi everyone,&lt;/p&gt;
&lt;p&gt;I’d like some advice/opinions on how to test some existing code. It’s a web application using Spring and struts.&lt;/p&gt;
&lt;p&gt;I have a class called the ProcessedFilesManager which contains a number of methods used by Struts Action classes. This manager communicates with five different DAOs to get the information that some of the Struts actions are interested in. Now, I want to test this manager class (ProcessedFilesManager). The way I’ve started doing it is stubbing up each of the five DAOs, however, this is proving to be quite painful. I didn’t want to use a mocking approach, nor did I want to use a DB solution like Hypersonic, but now I’m open to suggestions.&lt;/p&gt;
&lt;p&gt;Seeing as there a number of approaches I could use, what do you think would be best for this situation?&lt;/p&gt;
&lt;p&gt;It feels wrong to stub the DAOs because what if I’m introducing behaviour in there that differs from the actual DAOs? My tests will not be accurate.&lt;/p&gt;
&lt;p&gt;Any advice/comments would be much appreciated.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://groups.yahoo.com/neo/groups/testdrivendevelopment/conversations/topics/27079&quot;&gt;Read the thread&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I used to have this fear, and I do something now that has eliminated that fear.&lt;/p&gt;
&lt;p&gt;When I stub a DAO method, I make an assumption about what that DAO method does. I used to be worried about making the wrong assumption, but now I have a &lt;strong&gt;contract test&lt;/strong&gt; for the DAO interface that tests for the assumption I’m making in my Service test. The contract test gives me confidence that any implementation of the DAO method passes the same tests, so every implementation of that DAO method behaves &lt;strong&gt;in ways that the clients rely on&lt;/strong&gt;. Once I have this, I feel comfortable stubbing that DAO method that way in a Service test.&lt;/p&gt;
&lt;p&gt;A contract test describes the behavior of an interface. I describe contract tests in some detail in &lt;a href=&quot;https://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FJUnit-Recipes-Practical-Methods-Programmer%2Fdp%2F1932394230%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1199051730%26sr%3D8-1&amp;amp;tag=masterprogram-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325&quot;&gt;JUnit Recipes&lt;/a&gt;, recipe 2.6, although back then I called them “abstract test cases” because I hadn’t yet discovered the better name “contract test”. If you prefer, I’ve provided a diagram showing some contract tests for a typical DAO class.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://images.jbrains.ca/StubYourWorriesAway/ContractTests.jpg&quot; style=&quot;width: 100%; align: center;&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
Since classes inherit methods from their superclasses, the &lt;code&gt;Hibernate Customer DAO Test&lt;/code&gt; will inherit the &lt;em&gt;contract tests&lt;/em&gt; from its superclass, as will the &lt;code&gt;JDBC Customer DAO Test&lt;/code&gt;. This means that each implementation has to pass not only its own tests (like &lt;code&gt;testClosesSession()&lt;/code&gt; or &lt;code&gt;testClosesResultSet()&lt;/code&gt;) but also the tests inherited from &lt;code&gt;Customer DAO Contract Test Template&lt;/code&gt;. (I call it a “template” because it plays the role of template in the Template Method design pattern.) When you test-drive a new implementation of &lt;code&gt;Customer DAO&lt;/code&gt;, simply make the new test extend the contract test template and you’ll automatically inherit its contract tests. This way, I have confidence that any implementation of &lt;code&gt;Customer DAO&lt;/code&gt; behaves the way I’d expect any &lt;code&gt;Customer DAO&lt;/code&gt; to behave.
&lt;/p&gt;
Returning to our example, these contract tests give me confidence to stub the DAO when I test-drive the Service, and that confidence brings with it a happy side effect. I am confident that &lt;code&gt;findAllWithPendingOrders()&lt;/code&gt; only returns customers with pending orders, so I don’t have to worry about that issue at all when I design the Service that reports all customers with pending orders. Now that I notice it, &lt;code&gt;Report All Customers With Pending Orders Service&lt;/code&gt; is really just a &lt;code&gt;Report on Customers Service&lt;/code&gt; that needs a &lt;code&gt;Customer Filter&lt;/code&gt;, which could be a &lt;code&gt;Pending Orders Customer Filter&lt;/code&gt;. I don’t think I would have felt comfortable with this level of generalization if I weren’t so confident in the way I’ve separated the responsibilities.
&lt;/p&gt;
&lt;p&gt;The next time you want to avoid stubbing a method because you’re worried you’ll make a wrong assumption about what the method does, try writing enough contract tests to give you the confidence you need. I think you’ll like the results.&lt;/p&gt;
</description>
        <pubDate>Thu, 23 Sep 2010 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/stub-your-data-access-layer-it-wont-hurt</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/stub-your-data-access-layer-it-wont-hurt</guid>
        
        
      </item>
    
      <item>
        <title>When is it safe to introduce test doubles?</title>
        <description>&lt;p&gt;
I recently read &lt;a href=&quot;https://tinyurl.com/23yh3q&quot;&gt;this article at mockobjects.com&lt;/a&gt; and it reminded me of advice I give when I teach people about test doubles.
&lt;/p&gt;
&lt;p&gt;
At some point after you learn how to use test doubles, and perhaps dabble with JMock or Mocha, you notice that you’re using test doubles &lt;em&gt;everywhere&lt;/em&gt;. With any luck, you notice it, stand back, scratch your head, then wonder, “What exactly am I testing here?” If you’ve reached that stage, then you’re ready for this advice.
&lt;/p&gt;
&lt;p&gt;
First, remember that everything in your system is either a Service, Entity or Value. I didn’t make those names up: I learned them from Eric Evans in Domain-Driven Design.
&lt;/p&gt;
&lt;p&gt;
A &lt;em&gt;value&lt;/em&gt; has no lifecycle, is usually immutable and behaves with value semantics. This last point mostly means that “equals” depends on the value and not the location in memory. Strings, numbers, points, lists, monetary amounts, intervals, instants in time, these are values.
&lt;/p&gt;
&lt;p&gt;
An &lt;em&gt;entity&lt;/em&gt; has a lifecycle, is usually persisted, and behaves with ID semantics. That means that two entities can look the same by value, but represent different things, and therefore aren’t equal. Think of George Foreman’s kids, all named George. If your system only stores the child’s name and its parents’ names, then all those Georges look the same, but each is unique as a snowflake. Entities often use values. People, accounts, banks, transactions, these are entities.
&lt;/p&gt;
&lt;p&gt;
A &lt;em&gt;service&lt;/em&gt; co-ordinates work and provides an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; for applications to use it. A service is transient, can be pluggable and is often best when stateless. The notion of equality doesn’t much make sense for a service, and in many applications, one instance of a service is enough. (That doesn’t mean services should be singletons in the Gang of Four sense! They might be singletons in the Spring dependency injection container sense.) Services mostly figure out which entities need changing or retrieving, then either change or retrieve them. Transfer funds, deposit, withdraw, post interest, these are services.
&lt;/p&gt;
&lt;p&gt;
Now that we have a common language that’s probably wrong, but suitable enough for the current purpose, here is the advice I have to offer.
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
Never mock values, sometimes mock entities, but mock services freely.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
That’s the version that’s easy to remember. Here’s the longer answer.
&lt;/p&gt;
&lt;p&gt;
If you want to mock a value, then you’re not using it as a value, or your “value” is really trying to be an entity, or worse, a service. Values just are. They don’t persist themselves, they don’t find themselves… you just instantiate them, calculate with them, then throw them away. Entities will typically hold onto them, and when entities persist, the values go with them, but typically, that’s the entity’s concern, and not the value’s. A value should be so simple that there’s no benefit to mocking them. You should have no test doubles for values. If you do, it’s time to uncover what mislaid responsibility your value has, extract it out, then try again.
&lt;/p&gt;
&lt;p&gt;
You might want to mock an entity, but more likely you want to mock how you got the entity. Again, I use the term I learned from Evans: Repository. A repository is a place to look up and store entities. A repository is a service for keeping track of entities. Most of the time, I should be able to instantiate an entity and use it, so there’s no need to use a test double in its place. Typically, when you think you want to mock an entity, first try mocking the repository from whence it came.
&lt;/p&gt;
&lt;p&gt;
Services, you can mock with impunity. In fact, the only time not to mock a service is when you’re testing the service. Since services are typically interfaces and pluggable, you’ll want to use test doubles when you test how the application uses the service, or how a service uses another service. Since services tend to use repositories, entities and values, when you test the service, you’ll likely use test doubles for the repositories, but not for the entities nor the values.
&lt;/p&gt;
&lt;p&gt;
So that’s a summary of when I mock what. Of course, given that “mock” makes a great verb, and given the history of the term, I used mock in the foregoing mainly as a general term for “substituting a test double”, which I generally don’t like to do. I apologize for that. If this were going in a book, I’d be far more careful. There are several types of test double: mock, spy, stub, fake, dummy… &lt;a href=&quot;https://legacy.thecodewhisperer.com/post/1121571119/when-to-fake-when-to-mock&quot;&gt;I once wrote about when to fake and when to mock&lt;/a&gt;, so read that if you’re confused about how to use the different kinds of test doubles.
&lt;/p&gt;
&lt;p&gt;
I hope you found this useful, and if you didn’t, tell me why and I’ll find a way to make it up to you.
&lt;/p&gt;
</description>
        <pubDate>Tue, 14 Sep 2010 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/when-is-it-safe-to-introduce-test-doubles</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/when-is-it-safe-to-introduce-test-doubles</guid>
        
        
      </item>
    
      <item>
        <title>RSpec, have_tag(), Spec::Matcher and Nokogiri</title>
        <description>&lt;p&gt;One of my faithful readers at &lt;a href=&quot;https://www.jbrains.ca&quot;&gt;https://www.jbrains.ca&lt;/a&gt; told me that he couldn’t find an RSS feed icon in his Firefox address bar. I thought I could implement that fairly easily, so I agreed to do it. In the process, I wrote this spec:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/306627.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;Ruby follows the Principle of Least Surprise, so I tried this:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/306629.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;That doesn’t work, as I found no &lt;code&gt;#with_attribute&lt;/code&gt; nor anything like it. After I dug a little, I found out that I should write this:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/306632.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;I don’t like this, because it checks two things at once: it looks for an “RSS tag” and checks the &lt;code&gt;href&lt;/code&gt; attribute. That HTML implemented the “RSS tag” as attributes on &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; creates the confusion. The extremist in me calls this an &lt;a href=&quot;https://www.jbrains.ca/integrated_tests_are_a_scam&quot;&gt;integrated test&lt;/a&gt;, but I prefer not to go there today. Suffice it to say that when this check failed, I didn’t immediately know why, and I insist on immediately knowing why a check fails. When I’ve done this in the path with XPath assertions in XHTMLUnit or XMLUnit, I’ve resorted to writing duplicate checks that build on one another, so I tried that here:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/306634.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;Here I sacrificed duplication to improve the clarity of the assertions. I just now noticed that that contradicts my usual rule that removing duplication matters more than improving clarity. I dno’t know what to say about that just yet. Even if I remove the duplicate code, I still have the duplicate check, so extracting to a method won’t really do much here. I want &lt;code&gt;#with_attribute&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Not deterred, I tried introducing a custom RSpec matcher, since I don’t know what benefit that would give me, but it would benefit me somehow. When I tried to do that, RSpec told me that it couldn’t understand &lt;code&gt;response.should have_tag&lt;/code&gt; because it couldn’t find a &lt;code&gt;has_tag?&lt;/code&gt; on the response. I didn’t like the looks of the stack trace; I felt I would have to delve deeply into RSpec or &lt;code&gt;assert_select&lt;/code&gt;, and I didn’t find myself in the mood to do either, so I switched to Nokogiri.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/306635.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;Here I got to write the spec the way I wanted to: assume you will find “RSS feed tag”, then check that its &lt;code&gt;href&lt;/code&gt; attribute matches the right URL. If the response has no “RSS feed tag” at all, then complain violently, because of the higher severity of the mistake.&lt;/p&gt;
&lt;p&gt;Of course, if you have another suggestion, I’d like to see it. Add your comment below.&lt;/p&gt;
&lt;p&gt;Special thanks to &lt;a href=&quot;https://bit.ly/a3P4aU&quot;&gt;Frivolog&lt;/a&gt; for helping me get the original &lt;code&gt;have_tag&lt;/code&gt; code working.&lt;/p&gt;
</description>
        <pubDate>Fri, 19 Feb 2010 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/rspec-havetag-specmatcher-and-nokogiri</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/rspec-havetag-specmatcher-and-nokogiri</guid>
        
        
      </item>
    
      <item>
        <title>&quot;Integration Tests are a Scam&quot; is a Scam</title>
        <description>&lt;p&gt;
I made this announcement at a &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; course in Bucuresti this week, and I wanted to make it here: I now fully and freely admit that when I use the term “integration tests” I confuse people unnecessarily, and so I will stop.
&lt;/p&gt;
&lt;p&gt;
As a result, you will notice me change from “integration tests” to “integrated tests”, because I believe the latter term better fits the meaning I intend to convey as well as avoids confusion with what everyone else means by “integration tests”. I agree to reserve the term “integration tests” for tests that focus on checking the integration points between subsystems, systems, or any nontrivial client/supplier relationship. Integration tests might be integrated tests, and might be collaboration tests. Your choice.
&lt;/p&gt;
&lt;p&gt;
I apologize for the confusion I created, and appreciate you for hanging in there while I refactor my considerable library of legacy articles. That will take time and I can’t make it my full-time job.
&lt;/p&gt;
</description>
        <pubDate>Sun, 14 Feb 2010 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/integration-tests-are-a-scam-is-a-scam</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/integration-tests-are-a-scam-is-a-scam</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Using Integration Tests Mindfully: A Case Study</title>
        <description>&lt;aside&gt;
I wrote this article long enough ago that it refers to “integration tests”, when I really meant “integrated tests”. I have chosen to leave this article unedited, in part because this article underscores the problems behind my having called them “integration tests”. Sorry about that, folks.
&lt;/aside&gt;
&lt;div style=&quot;float: right; max-width: 200px; margin-left: 1em; margin-bottom: 1em;&quot; data-markdown=&quot;1&quot;&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/using-integration-tests-mindfully-a-case-study/GusPower.png&quot; title=&quot;Gus Power&quot; alt=&quot;Gus Power&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Gus Power&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;Gus Power commented about the way he uses integration tests in his work.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interesting series of articles &amp;amp; comments. I also read Steve Freeman’s article in response to the same topic. It’s got me thinking about how we work and I thought I’d take the time to describe it here.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;You define an integration test as “… any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior.” We have many such components that exhibit such non-trivial behaviour in the products we create, many of which are not developed by us. And we have integration tests to verify they work. I’m not just talking about 3rd party libraries and frameworks here, I’m referring to the whole system: caching layers. load balancers, &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; servers, CDNs, virtualization etc. When we build software it only becomes a product or service for our users when it has been deployed into a suitable environment; an environment that typically contains more than just the software we have written and packaged. Since our users’ experience and perception of quality result from their interaction with a deployed instance of the whole system, not just their interaction with the software at a unit level, we have come to value end-to-end integration testing. I believe there’s merit in testing these components in symphony and will attempt to clarify what kind of integration testing I’m talking about.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For a given piece of functionality we write an executable acceptance test in human readable form (for web projects we typically use some domain-specific extensions to selenium, for services we have used &lt;span class=&quot;caps&quot;&gt;FIT&lt;/span&gt; and it’s ilk, sometimes we roll our own if there’s nothing expressive enough available). We run it against a deployed version of the application (usually local though not always) which typically has a running web/application server and database. The test fails. We determine what endpoint needs to be created/enhanced and then we switch context down into unit-test land. A typical scenario would involve enhancing a unit test for the url mappings, adding one for the controller, then one for any additional service, domain object etc. When we’re happy and have tested and designed each of the required units we jump back up a level and get our acceptance test to progress further. The customer steers the development effort as he sees vertical ‘slices’ of functionality emerge. The acceptance test is added to a suite for that functional area. The continuous build system will then execute that test against a fully deployed (but scaled down) replica of the production environment, with hardware load balancer, vlans, multiple nodes (session affinity) and so forth. Any additional environmental monitoring (e.g. nagios alerting) is also done as part of this development effort and is deployed into the test environment along with the updated code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Setting up the infrastructure to do this kind of testing takes investment, both initial and ongoing. The continuous build needs to be highly ‘parallelized’ so you get feedback from a checkin in 10 mins or less (we’re heavy users of virtualization, usually VMWare or OpenVZ). The individual acceptance test suites need to be kept small enough to run quickly before check-in.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Benefits of this approach&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The continuous context-switch between acceptance test and unit test is key to our staying focused on delivering what the customer actually wants.&lt;/li&gt;
&lt;li&gt;The customer has multiple feedback points that he can learn from and use to steer the development effort.&lt;/li&gt;
&lt;li&gt;It confirms that the whole system works together – networking, &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt;, load balancing, automated deployment, session handling, database replication etc.&lt;/li&gt;
&lt;li&gt;We create additional ‘non-functional’ acceptance tests that automatically exercise other aspects of the system such as fail-over and recovery.&lt;/li&gt;
&lt;li&gt;Upgrades to parts of the system (switches, load balancers, web caches, library versions, database server versions etc.) can be tested in a known and controlled way.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;We’ve caught a number of integration-related issues using this approach (a few examples: broken database failover due to missing primary keys, captcha validation not working due to a web cache not behaving correctly, data not persisting because one database server had the wrong locale) and stopped them before they have reached our users. We have used the feedback as a basis for improving our products and their delivery at a system level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;OK this reply has now become far too long :-/ It would of course be good to discuss this in person sometime :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;—Gus Power&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thanks for the substantial comment, Gus. For those who don’t know Gus, he is one of the joint recipients of the 2009 Gordon Pask Award for contribution to Agile practice. I invite you to &lt;a href=&quot;https://www.energizedwork.com/&quot;&gt;follow his work and learn from his example&lt;/a&gt;. On to the substance of Gus’ comment.&lt;/p&gt;
&lt;p&gt;Gus, it appears you do not use integration tests to check basic behavior exhaustively. While I try not to use integration tests to check basic behavior at all, I mostly hope to stop programmers from attempting to write exhaustive integration tests that check basic correctness conditions. I wrote in &lt;a href=&quot;/permalink/not-just-slow-integration-tests-are-a-vortex-of-doom&quot;&gt;Not Just Slow: Integration Tests are a Vortex of Doom&lt;/a&gt; about the vicious cycle I see when teams rely on integration tests to check basic correctness. I encourage them to stop that particular insanity. I would hesitate to use integration tests as even smoke tests for basic correctness, but if I found myself in a situation where I needed to write such tests, I’d do it, then look for ways to render them obsolete.&lt;/p&gt;
&lt;p&gt;Also, you mention writing “human-readable acceptance tests”, and I certainly use such tests in my work. When I counsel against using integration tests, I advise it within the context of programmer tests only. While I strongly encourage teams to allow even some of their acceptance tests to check policy or business rule behavior directly and in isolation, I understand and agree that one generally needs to write some acceptance tests as integration tests.&lt;/p&gt;
&lt;p&gt;In general, you describe using integration tests quite purposefully, mindfully, and responsibly. I expect no less from a practitioner of your caliber. I would truly enjoy working with you on a project.&lt;/p&gt;
&lt;p&gt;Finally, you mention that your integration tests catch system-level issues, such as a broken database schema, mistaken cache integration, and so on. I expect integration tests to find only, or at least mostly, these problems. None of these sound like basic correctness problems.&lt;/p&gt;
&lt;p&gt;So Gus, I appreciate you for writing a great description of using integration tests well. I wish we had more examples like this. I truly wish I &lt;strong&gt;saw&lt;/strong&gt; more examples like this. Sadly, I don’t: I see teams trying to check basic correctness issues with plodding, brittle, misleading tests. For those, I stress the need to eliminate integration tests.&lt;/p&gt;
</description>
        <pubDate>Sun, 31 Jan 2010 08:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/using-integration-tests-mindfully-a-case-study</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/using-integration-tests-mindfully-a-case-study</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Not Just Slow: Integration Tests are a Vortex of Doom</title>
        <description>&lt;aside&gt;
I wrote this article long enough ago that it refers to “integration tests”, when I really meant “integrated tests”. I have chosen to leave this article unedited, in part because this article underscores the problems behind my having called them “integration tests”. Sorry about that, folks.
&lt;/aside&gt;
&lt;style type=&quot;text/css&quot;&gt;
.reader-comment { font-size: small; font-weight: italic; }
.float-right {
  float: right;
  padding-left: 1rem;
  padding-bottom: 1rem;
}
&lt;/style&gt;
&lt;p&gt;My friend, Artem Marchenko, had a comment about my recent writing against &lt;del&gt;integration&lt;/del&gt; integrated tests.&lt;/p&gt;
&lt;div class=&quot;float-right&quot; style=&quot;max-width: 200px&quot;&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/not-just-slow-integration-tests-are-a-vortex-of-doom/ArtemMarchenko.jpg&quot; title=&quot;Artem Marchenko&quot; alt=&quot;Artem Marchenko&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;Artem Marchenko&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;“Aha! So &lt;span class=&quot;citation&quot; data-cites=&quot;jbrains&quot;&gt;@jbrains&lt;/span&gt; is really against the integration tests just because they are too slow for hourly use”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It reminds me about the Ferrari IT story (XP team, dozens of deployments a year on many continents) that started from getting a big visible counter of a total number of tests and wrote just big amount of &lt;strong&gt;any&lt;/strong&gt; tests first. You need to start somewhere and getting large integration tests is definitely better than nothing. As long as you are prepared to improve the testing practices later. —Artem Marchenko&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I agree with this sentiment. I tell the story of my very first attempt at test-first programming&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, how I wrote about 125 tests, many of which fit my definition of “integration test”, and which took 12 minutes to execute. This meant that, on average, I only made 8-12 edits per hour when writing that code. I recognized then, and I still recognize now, that even making only 8-12 edits per hour—4-6 edits per hour towards the end—that I produced better software than I did when I would write code almost continuously for several hours at a time. As much as I disparage those integration tests today, I appreciated them a great deal at the time I wrote them. I find integration tests useful for finding system-level problems, as the first step in fixing a mistake, and if I genuinely can’t write a focused object test, then I will usually write an integration test.&lt;/p&gt;
&lt;p&gt;As you say, Artem, I simply don’t stop there.&lt;/p&gt;
&lt;p&gt;When I label integration tests a &lt;em&gt;scam&lt;/em&gt;, I mean to emphasize the self-replicating nature of integration tests. It starts simply enough: you write a handful of integration tests, which give you a lot of freedom to implement your design in a way that introduces unfortunate dependencies, which makes focused object testing quite difficult. As a result, you will probably resign yourself to writing more integration tests, which do nothing to improve your dependency problems, and the cycle begins again.&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;/images/not-just-slow-integration-tests-are-a-vortex-of-doom/cycle-of-pain-1.jpg&quot; title=&quot;The Cycle of Pain&quot; alt=&quot;The Cycle of Pain&quot; /&gt;&lt;figcaption aria-hidden=&quot;true&quot;&gt;The Cycle of Pain&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Integration tests help cause pain, even though they appear to help reduce pain. Therein lies the scam.&lt;/p&gt;
&lt;p&gt;I must acknowledge this: if you started writing tests this week, or this month, or even this year, then you will probably benefit more from writing integration tests than trying to write perfectly focused object tests. I have said and written elsewhere that I believe a programmer needs to write about 1500 to burn into her brain the basic patterns of good tests. Even so, as you write those tests, I want you to remain aware of the cost. Even if you don’t know how to write a good, focused object test, if you &lt;em&gt;want&lt;/em&gt; to write more such tests, and especially if you &lt;em&gt;try&lt;/em&gt; to write more such tests, then I will have completed the first phase of my mission to eradicate programmer reliance on integration tests to show the basic correctness of their code.&lt;/p&gt;
&lt;p&gt;Join us! Turn one integration test into a small suite of focused object tests today. If you don’t yet see how to replace an entire integration test with equivalent focused object tests, then write at least one or two focused object tests along side the integration test. Try it. I promise, you’ll like it.&lt;/p&gt;
&lt;p&gt;One last comment to my good friend Artem: please don’t &lt;a href=&quot;https://duckduckgo.com/?q=lullaby+words&quot;&gt;put me to sleep&lt;/a&gt; with the word “just”!&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I use the term &lt;em&gt;test-first programming&lt;/em&gt; to refer to test-driven design without the evolutionary design part. With test-first programming, I develop a specific design, then I use tests to help me type it in correctly.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 28 Jan 2010 08:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/not-just-slow-integration-tests-are-a-vortex-of-doom</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/not-just-slow-integration-tests-are-a-vortex-of-doom</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>What your tests don&apos;t need to know will hurt you</title>
        <description>&lt;style type=&quot;text/css&quot;&gt;
.rule { display: block; margin-left: 5%; margin-right: 5%; border: 3px solid; padding: 1em; }
.novice { display: block; margin-left: 5%; margin-right: 5%; font-style: bold; border: 3px solid; background-color: white; color: black; padding: 1em }
.aside { display: block; margin-left: 5%; margin-right: 5%; border: 1px solid; background-color: lightyellow; padding: 1em }
&lt;/style&gt;
&lt;p&gt;I just finished reading Brian Marick’s article, &lt;a href=&quot;https://bit.ly/7WYg5i&quot;&gt;“Mocks, the removal of test detail, and dynamically-typed languages”&lt;/a&gt;, which focused me on a design technique I use heavily: awareness of irrelevant details in tests. Referring back to &lt;a href=&quot;https://bit.ly/2s96DC&quot;&gt;the four elements of simple design&lt;/a&gt;, I focus on irrelevant details in tests in order to help me maximize clarity in production code. Please allow me to sketch the ideas here.&lt;/p&gt;
&lt;p&gt;I use the term &lt;em&gt;irrelevant detail&lt;/em&gt; to refer to any detail that does not contribute directly to the correctness of the behavior I’ve chosen to check. I know when I’ve bumped into an irrelevant detail: while writing the code that allows me to check something, I start typing something, then my shoulders slump and I exhale with annoyance. I think, &lt;em&gt;I shouldn’t have to write this, because it has nothing to do with what I want to check&lt;/em&gt;. Brian’s example illustrates this perfectly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The random methods save a good deal of setup by defaulting unmentioned parameters and by hiding the fact that Reservations have_many Groups, Groups have_many Uses, and each Use has an Animal and a Procedure. But they still distract the eye with irrelevant information. For example, the controller method we’re writing really cares nothing for the existence of Reservations or Procedures–but the test has to mention them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I maintain one Ruby code base, which runs &lt;a href=&quot;https://www.jbrains.ca&quot;&gt;my weblog at jbrains.ca&lt;/a&gt; and I often find myself creating a &lt;code&gt;Posting&lt;/code&gt; object in my tests, and often the content of that posting doesn’t matter.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/276920.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;I use a simple rule to help me identify irrelevant data in tests.&lt;/p&gt;
&lt;p class=&quot;rule&quot;&gt;
If I can change a value without changing the result of the behavior I want to check, then I call that &lt;strong&gt;irrelevant data&lt;/strong&gt; for this test.
&lt;/p&gt;
&lt;p&gt;I first identify data as irrelevant and mark it that way. For string values, I include the word “irrelevant” in the string. Some people use words like “dummy” for this purpose, but I prefer “irrelevant”, because I don’t want others to confuse an irrelevant detail for &lt;a href=&quot;https://bit.ly/5hU90b&quot;&gt;a type of stub&lt;/a&gt;. I used to simply choose random values for irrelevant data, because I had read that good testing principles included varying data from test to test. Now I feel that choosing especially meaningful-looking values for irrelevant data obscures the purpose of a test.&lt;/p&gt;
&lt;p&gt;Irrelevant data can hurt in a number of ways.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You might “play it safe” and duplicate the irrelevant data in more tests, leading to &lt;a href=&quot;https://bit.ly/5ljblU&quot;&gt;excess investment&lt;/a&gt; in maintaining your tests.&lt;/li&gt;
&lt;li&gt;You might “play it safe” and check the irrelevant data in your test, leading to misleading failures as you change unrelated behavior in the system.&lt;/li&gt;
&lt;li&gt;Changing the data might affect the result (pass/fail) of your test even though the data does not relate conceptually to the behavior you want to check.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I estimate that I have experienced more pain from this last effect than from all other effects combined.&lt;/p&gt;
&lt;p&gt;Once I have identified and labeled irrelevant data, I look for ways to eliminate it. Moving irrelevant data into fixtures or &lt;a href=&quot;https://natpryce.com/articles/000714.html&quot;&gt;test data builders&lt;/a&gt;, hides the symptoms without solving the problem. Ironically, moving irrelevant data into fixtures or test data builders merely makes that data easier to spread to more tests to which they do not relate, creating more, not less, potential for unhealthy dependency. It masks the very kind of observation that Brian made in his code base. Sometimes, I write a test and notice that, for some piece of data, neither its value nor its type matters to me. I find this happens a lot when I test-drive controller behavior that takes data from a model and hands it directly to a view.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/276954.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;I notice here that &lt;code&gt;[1,2,3]&lt;/code&gt; represents “any non-empty array”. While writing this sentence, I wondered if I could change this to &lt;code&gt;Object.new&lt;/code&gt;, so I tried that, and the test passed. In this case, while the actual data and type don’t matter, I need the model to return anything but &lt;code&gt;nil&lt;/code&gt; to ensure that the view has &lt;em&gt;something&lt;/em&gt; and that that something came from the model. With this realization, I rewrote the test.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/276958.js&quot;&gt; &lt;/script&gt;
&lt;p&gt;Instead of &lt;code&gt;should ==&lt;/code&gt; I use &lt;code&gt;should equal()&lt;/code&gt; here, which translates to &lt;code&gt;assertSame()&lt;/code&gt; in other languages, to emphasize that I expect the controller to take whatever it receives from the model and hand it to the view. When I want to check what the view does with it, I’ll send valid data to the view and check it in isolation. When I want to check what the model returns, I’ll look at what the view expects and check that the model can provide it. The controller need not bother itself with the details.&lt;/p&gt;
&lt;p&gt;Compare this with the corresponding integration test for checking the controller, which would require knowing all these otherwise irrelevant things and setting all this otherwise irrelevant data…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to create a &lt;code&gt;Posting&lt;/code&gt; in the database in the “queued for publication” state, which means setting the &lt;code&gt;queued_at&lt;/code&gt; attribute to a time in the past, but the &lt;code&gt;published_at&lt;/code&gt; attribute to &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;How to instantiate a valid &lt;code&gt;Posting&lt;/code&gt;, which requires &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;content&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Which view the controller renders when it displays the publication queue.&lt;/li&gt;
&lt;li&gt;Which attributes of the &lt;code&gt;Posting&lt;/code&gt; the view expects, to ensure that I populate them with valid, if meaningless, data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I suppose I could think of more irrelevant behavior and data, but this will do. How does this irrelevant data and behavior hurt specifically in this situation?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I have this note in my problems list: “A Posting can be both queued and published. I want to remove this possibility, rather than forcing Posting to maintain the invariant.” When I fix this problem, my controller test will change, even though I won’t have changed the controller.&lt;/li&gt;
&lt;li&gt;If I added a mandatory attribute to &lt;code&gt;Posting&lt;/code&gt;, then my controller test would change, even though I wouldn’t have changed the controller.&lt;/li&gt;
&lt;li&gt;If I removed a mandatory attribute from &lt;code&gt;Posting&lt;/code&gt;, then my controller test would have even more irrelevant data, meaning more accidental ways to go wrong.&lt;/li&gt;
&lt;li&gt;If I changed the view that the &lt;code&gt;:new&lt;/code&gt; action renders, then my controller test would change, even though I wouldn’t have changed the controller behavior that my test checks.&lt;/li&gt;
&lt;li&gt;If I changed which attributes of &lt;code&gt;Posting&lt;/code&gt; the view processed, then my controller test would either need to change or contain even more irrelevant details than it did before.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I write that &lt;a href=&quot;https://bit.ly/8uQruT&quot;&gt;integrated tests are a scam&lt;/a&gt;, I include as a reason that writing integration tests encourages including irrelevant details in tests, and by now I hope I’ve shown some ways that that hurts. All this leaves me with a few guiding principles to use when writing tests.&lt;/p&gt;
&lt;p class=&quot;rule&quot;&gt;
A test should make it clear how its expected output relates to its input.
&lt;/p&gt;
&lt;p class=&quot;aside&quot;&gt;
I looked back at &lt;a href=&quot;https://bit.ly/7deOZD&quot;&gt;“JUnit Recipes”&lt;/a&gt; to find out whether I’d mentioned this guideline back then. I couldn’t find it.
&lt;/p&gt;
&lt;p&gt;I can use this guiding principle to develop some &lt;a href=&quot;https://bit.ly/sYj5Y&quot;&gt;Novice rules&lt;/a&gt;:&lt;/p&gt;
&lt;p class=&quot;novice&quot;&gt;
Mark all irrelevant data in a test by extracting the values to variables whose name includes the word “irrelevant”.
&lt;/p&gt;
&lt;p class=&quot;novice&quot;&gt;
Hide all irrelevant data using techniques like the &lt;a href=&quot;https://bit.ly/2oJaTU&quot;&gt;Test Data Builder pattern&lt;/a&gt;. Remember to remove duplication after hiding irrelevant data.
&lt;/p&gt;
&lt;p class=&quot;novice&quot;&gt;
Call attention to all input values that have a direct bearing on computing the expected result in a test.
&lt;/p&gt;
&lt;p&gt;Beyond these novice rules, this guiding principle helps in two key ways. Certainly, it encourages me to write shorter, more focused tests, which tend to have &lt;a href=&quot;https://bit.ly/6PlzxY&quot;&gt;all the properties I want in a test&lt;/a&gt;, but more importantly, it leads me to a higher guiding principle when writing tests.&lt;/p&gt;
&lt;p class=&quot;rule&quot;&gt;
When you find it difficult to write a concise, focused, isolated test, the production code has unhealthy dependencies to loosen, invert, or break.
&lt;/p&gt;
&lt;p&gt;Here, “concise” means having no irrelevant details; “focused” means failing for only one reason; “isolated” means executing without side effects on other tests.&lt;/p&gt;
&lt;p&gt;I loosen dependencies by applying the &lt;a href=&quot;https://bit.ly/6qPmLI&quot;&gt;Generalize Declared Type&lt;/a&gt; refactoring. I most commonly invert dependencies by &lt;a href=&quot;https://bit.ly/4DAxuL&quot;&gt;extracting an interface&lt;/a&gt; and using &lt;a href=&quot;https://bit.ly/6oNM2x&quot;&gt;constructor injection&lt;/a&gt;. I most commonly break dependencies by either extracting a &lt;a href=&quot;https://bit.ly/5RtSNi&quot;&gt;memento&lt;/a&gt; or the return value of a method and depending on that, rather than the original object.&lt;/p&gt;
&lt;p&gt;This guiding principle leads me in the direction of &lt;em&gt;The Fundamental Theorem of Test-Driven Development&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Assuming we know what we want to check and understand the mechanics of how to check it, difficulty checking behavior means unhealthy dependencies in the design.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Thu, 14 Jan 2010 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/what-your-tests-dont-need-to-know-will-hurt-you</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/what-your-tests-dont-need-to-know-will-hurt-you</guid>
        
        
      </item>
    
      <item>
        <title>Surely the Mars rover needed integrated tests! (Maybe not?)</title>
        <description>&lt;h2 id=&quot;the-30-second-version&quot;&gt;The 30-second version&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I can find integration problems of basic correctness without integrated tests using a simple double-entry book-keeping approach.&lt;/li&gt;
&lt;li&gt;I use test doubles to articulate the assumptions I make in my design; these become tests for the next layer.&lt;/li&gt;
&lt;li&gt;You don’t need to do TDD to use this technique: you can use it when adding tests to existing or legacy code.&lt;/li&gt;
&lt;li&gt;This technique makes rescuing legacy code easier, since you can write more tests without having to deploy the system in its usual runtime environment.&lt;/li&gt;
&lt;li&gt;Most programmers write good collaboration tests, but forget to write contract tests, and that creates integration problems, so write contract tests!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-details&quot;&gt;The Details&lt;/h2&gt;
&lt;p&gt;
“Guest” commented about my Agile 2009 tutorial, Integration Tests Are A Scam. “Guest” wrote this:
&lt;/p&gt;
&lt;blockquote style=&quot;font-style: italic;&quot;&gt;
&lt;span class=&quot;drop-quote&quot;&gt;“&lt;/span&gt;A Mars rover mission failed because of a lack of integrated tests. The parachute system was successfully tested. The system that detaches the parachute after the landing was successfully – but independently – tested. On Mars when the parachute successfully opened the deceleration “jerked” the lander, then the detachment system interpreted the jerking as a landing and successfully detached the parachute. Oops. Integration tests may be costly but they are absolutely necessary.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I don’t doubt the necessity of integrated tests. I depend on them to solve difficult system-level problems. By contrast, I routinely see teams using them to detect unexpected consequences, and I don’t think we need them for that purpose. I prefer to use them to confirm an uneasy feeling that an unintended consequence lurks.
&lt;/p&gt;
&lt;p&gt;
Let’s consider a clean implementation of the situation my commenter describes. I see this design, comprising the lander, the parachute, the detachment system, an accelerometer and an altimeter. A controller connects all these things together. Let’s look at the “code”, which I’ve written in a fantasy language that looks a little like Java/C# and a little like Ruby.
&lt;/p&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;
Ashley Moran has posted a working Ruby version of this example. If you speak Ruby, then I highly recommend &lt;a href=&quot;https://link.jbrains.ca/1uOh366&quot;&gt;looking at that example&lt;/a&gt; after you’ve read this.}
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;&gt;
&lt;div id=&quot;gist-185020&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;Controller.initialize() {               &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;detachment_system = DetachmentSystem.new(parachute)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = Accelerometer.new()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;lander = Lander.new(accelerometer, Altimeter.new())&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.add_observer(detachment_system)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;Parachute {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&amp;nbsp;needs a lander&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC12&quot;&gt;&amp;nbsp;&amp;nbsp;open() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC13&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.decelerate()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC14&quot;&gt;&amp;nbsp;&amp;nbsp;}             &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC15&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC16&quot;&gt;&amp;nbsp;&amp;nbsp;detach() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC17&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (lander.has_landed == false)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC18&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise &amp;quot;You broke the lander, idiot.&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC19&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC20&quot;&gt;}      &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC21&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC22&quot;&gt;AccelerationObserver is a role {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC23&quot;&gt;&amp;nbsp;&amp;nbsp;handle_acceleration_report(acceleration) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC24&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise &amp;quot;Subclass responsibility&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC25&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC26&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC27&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC28&quot;&gt;DetachmentSystem acts as AccelerationObserver {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC29&quot;&gt;&amp;nbsp;&amp;nbsp;needs a parachute&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC30&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC31&quot;&gt;&amp;nbsp;&amp;nbsp;handle_acceleration_report(acceleration) {}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC32&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (acceleration &amp;lt;= -50.ms2) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC33&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC34&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC35&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC36&quot;&gt;}               &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC37&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC38&quot;&gt;Accelerometer acts as Observable {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC39&quot;&gt;&amp;nbsp;&amp;nbsp;manages many acceleration_observers&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC40&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC41&quot;&gt;&amp;nbsp;&amp;nbsp;report_acceleration(acceleration) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC42&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;acceleration_observers.each() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC43&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;each.handle_acceleration_report(acceleration)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC44&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC45&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC46&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC47&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC48&quot;&gt;Lander {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC49&quot;&gt;&amp;nbsp;&amp;nbsp;needs an accelerometer  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC50&quot;&gt;&amp;nbsp;&amp;nbsp;needs an altimeter&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC51&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC52&quot;&gt;&amp;nbsp;&amp;nbsp;decelerate() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC53&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// I know how much to decelerate by&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC54&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;accelerometer.report_acceleration(how_much)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC55&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC56&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC57&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185020/029126795025ebc095f05ef97b39af4ee0479c99/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185020&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
I need to test what happens when I open the parachute. The lander should decelerate.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185026&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testOpenParachute() { &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander.expects().decelerate() &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;parachute.open() &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185026/1f16f2e2e3513fdfb0e9434d2b3610353fd4a141/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185026&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Since this test expects the lander to decelerate, I have to test that. When the lander decelerates, the accelerometer should report its deceleration.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185027&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testLanderDecelerates() {                  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = mock(Accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander = Lander.new(accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.expects().report_acceleration(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;lander.decelerate()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185027/1ddf011da15152df20d4eba65e1b57ac94a638d0/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185027&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Since this test shows that the accelerometer can report acceleration of −50 m/s&lt;sup&gt;2&lt;/sup&gt;, I have to test that.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185029&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testAccelerometerCanReportRapidAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = Accelerometer.new()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.add_observer(observer = mock(AccelerationObserver))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;observer.expects().handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.report_acceleration(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}                                          &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185029/1f0bb87f14af33b5a1e361084f9d7681966d8216/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185029&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Since this test shows that any acceleration observer must be prepared to handle an acceleration report of −50 m/s&lt;sup&gt;2&lt;/sup&gt;, I have to test that.
&lt;/p&gt;
&lt;p&gt;
First, the general test for the contract of the interface:
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185030&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;AccelerationObserverTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testAccelerationObserverCanHandleRapidAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer = create_acceleration_observer() // subclass responsibility&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should execute_without_incident&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;}                                                      &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185030/0153625081492a73e556d06b394751ac7b60779e/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185030&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Now the test for &lt;code&gt;DetachmentSystem&lt;/code&gt;, which acts as an &lt;code&gt;AccelerationObserver&lt;/code&gt;. What should it do if it detects such sudden deceleration? It should detach the parachute.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185031&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystemTest extends AccelerationObserverTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;// I inherit  testAccelerationObserverCanHandleRapidAcceleration()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;create_acceleration_observer() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.expects().detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185031/67c2a266c7c9a5295d185869eb8abd338a13d770/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185031&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
You might find that easier to read this way, by inlining the method &lt;code&gt;create_acceleration_observer()&lt;/code&gt;:
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185032&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystemTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testRespondsToRapidAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system = DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.expects().detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should execute_without_incident&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}                              &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185032/9af808918a355eed88b3989b0b8b98ad5673194f/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185032&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Since this test expects the parachute to be able to detach, I have to test that. Now, detaching only works if we’ve landed. (I’ve simplified on purpose. Suppose the parachute can’t survive a drop from any height. It’s easy to add that detail in later.)
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185033&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;ParachuteTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testDetachingWhileLanded() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.stubs().has_landed().to_return(true)    &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should execute_without_incident&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&amp;nbsp;testDetachingWhileNotLanded() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC12&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.stubs().has_landed().to_return(false)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC13&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC14&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC15&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should raise(&amp;quot;You broke the lander, idiot.&amp;quot;)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC16&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC17&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC18&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185033/d566e795af04db2dc29e0da17b3cf8f8f8800b9d/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185033&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Hm. I notice that &lt;code&gt;parachute.detach()&lt;/code&gt; might fail. But I just wrote a test that uses &lt;code&gt;parachute.detach()&lt;/code&gt; and doesn’t yet show how it handles that method failing. I have to test that.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185034&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystemTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testRespondsToDetachFailing() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system = DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.stubs().detach().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185034/73eefaab8529f4a26a0488a6d34afe2e819286ed/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185034&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Hm. So handling an acceleration report of −50 m/s&lt;sup&gt;2&lt;/sup&gt; can fail. Who might issue such a right? The accelerometer. Since the detach system doesn’t handle this failure, I have to test what the accelerometer does when issuing an acceleration report might fail.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185035&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testAccelerometerCanRespondToFailureWhenReportingAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = Accelerometer.new()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.add_observer(observer = mock(AccelerationObserver))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;observer.stubs().handle_acceleration_report().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;accelerometer.report_acceleration(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185035/c86ed2c04981ab8050efe82ee530327449dde4f7/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185035&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
It turns out that the accelerometer might fail when reporting acceleration of −50 m/s&lt;sup&gt;2&lt;/sup&gt;. When might it do that? When the lander decelerates. What happens then?
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185036&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testLanderDeceleratesRespondsToFailure() {                  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = mock(Accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander = Lander.new(accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.stubs().report_acceleration().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.decelerate()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185036/eb192b978d1f3caa931ff1cfaaa1f296e45724d1/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185036&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Hm. So decelerating could fail! All right, who causes the lander to decelerate? That code might fail. Oh yes… the parachute opening!
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185037&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testOpenParachuteRespondsToFailure() { &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander.stubs().decelerate().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.open() &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;}  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185037/f3f719d33f6d216cb73c194e59bf1e899226205a/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185037&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
So opening the parachute could fail! We probably want to nail down when that happens. We have a test that shows us when:
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185038&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testDetachingWhileNotLanded() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander.stubs().has_landed().to_return(false)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(&amp;quot;You broke the lander, idiot.&amp;quot;)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185038/9a3256c986335fe66e3fbd06fbbde7f8a5a6365c/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185038&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
So the parachute opening could cause it to detach because the lander hasn’t landed yet. I don’t know about you, but I think the parachute provides the most value when its helps the lander land, and not once it has landed. That tells me that someone, somewhere needs to handle the exception that &lt;code&gt;detach()&lt;/code&gt; would raise, or at least prevent &lt;code&gt;detach()&lt;/code&gt; from happening while the altimeter reads above a few meters off the ground.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185039&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testDoNotDetachWhenTheLanderIsTooHighUp() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;altimeter = mock(Altimeter)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;altimeter.stubs().altitude().to_return(5.m)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;parachute.expects(no_invocations_of).detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&amp;nbsp;// ???&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC12&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185039/36dc5b6ee47ebbf219b808b39f474c3636ceb766/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185039&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
In writing this test, I see that in order to stop the detachment system from telling the parachute to detach, it needs access to the altimeter.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Integration problem detected.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
When I wire the detachment system up to the altimeter, even the collaboration test shows how to ensure that the parachute doesn’t detach in this kind of dangerous situation.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185040&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testDoNotDetachWhenTheLanderIsTooHighUp() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;DetachmentSystem.new(parachute = mock(Parachute), altimeter = mock(Altimeter))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;altimeter.stubs().altitude().to_return(5.m)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;parachute.expects(no_invocations_of).detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185040/28e7056741f7b7197816dddb2151b2af269c22a5/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185040&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
This means I have to add the following production behavior.
&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;//gist.github.com/stylesheets/gist/embed.css&quot;/&gt;
&lt;div id=&quot;gist-185041&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;gist-highlight&quot;&gt;
&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystem acts as AccelerationObserver {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;needs a parachute&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;needs an altimeter // NEW!&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;handle_acceleration_report(acceleration) {}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (acceleration &amp;lt;= -50.ms2 and altimeter.altitude() &amp;lt; 5.m) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;}               &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/raw/185041/75baea8b5de141d632b36eea6c569bcf0bcf5428/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt; &lt;a href=&quot;https://gist.github.com/185041&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Integration problem solved with no integrated tests. Instead, I have a bunch of collaboration tests, one important contract test, and &lt;del&gt;the ability to notice things&lt;/del&gt; a systematic approach to choosing the next test, which I describe in the comments below. Any questions?
&lt;/p&gt;
&lt;blockquote style=&quot;font-size: small; font-style: italic;&quot;&gt;
&lt;p style=&quot;font-size: small; font-style: italic;&quot;&gt;
Dan Fabulich rightly jumped on me for using the phrase “an ability to notice things” just a little earlier in this article. I choose that phrase lazily because I didn’t want to patronize you by writing, “an ability to perform basic reasoning”. Oops. I thought about how I choose the next test, and I decided to take the time to include that here. Enjoy.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
In this example, I used no magic to choose the next test; but rather some fundamental reasoning.
&lt;/p&gt;
&lt;p&gt;
Every time I say “I need &lt;em&gt;a thing&lt;/em&gt; to do &lt;em&gt;X&lt;/em&gt;” I introduce an interface. In my current test, I end up stubbing or mocking one of those tests.
&lt;/p&gt;
&lt;p&gt;
Every time I &lt;em&gt;stub&lt;/em&gt; a method, I make an assumption about what values that method can return. To check that assumption, I have to write a test that expects the return value I’ve just stubbed. I use only basic logic there: if A depends on B returning x, then I have to know that B can return x, so I have to write a test for that.
&lt;/p&gt;
&lt;p&gt;
Every time I &lt;em&gt;mock&lt;/em&gt; a method, I make an assumption about a service the interface provides. To check that assumption, I have to write a test that tries to invoke that method with the parameters I just expected. Again, I use only basic logic there: if A causes B to invoke c(d, e, f) then I have to know that I’ve tested what happens when B invokes c(d, e, f), so I have to write a test for that.
&lt;/p&gt;
&lt;p&gt;
Every time I introduce a method on an interface, I make a decision about its behavior, which forms the &lt;em&gt;contract&lt;/em&gt; of that method. To justify that decision, I have to write tests that help me implement that behavior correctly whenever I implement that interface. I write contract tests for that. Once again, I use only basic logic there: if A claims to be able to do c(d, e, f) with outcomes x, y, and z, then when B implements A, it must be able to do c(d, e, f) with outcomes x, y, and z (and possibly other non-destructive outcomes).
&lt;/p&gt;
&lt;p&gt;
I simply kept applying these points over and over again until I stopped needing tests. Along the way, I found a problem and fixed it before it left my hands.
&lt;/p&gt;
&lt;p&gt;
If I can describe the steps well enough for others to follow – and I posit I’ve just done that here – then I don’t agree to labeling it “magic”.
&lt;/p&gt;
</description>
        <pubDate>Wed, 30 Sep 2009 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/surely-the-mars-rover-needed-integrated-tests-maybe-not</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/surely-the-mars-rover-needed-integrated-tests-maybe-not</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Interlude: Basic Correctness</title>
        <description>&lt;p class=&quot;introductory-note&quot;&gt;
I tried to respond to a comment from James Bach, but surpassed the 3000-character limit, so I’ve decided to add this long comment as a short article.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: I don’t understand the point of calling a failure discovered by running a test “unjustifiable.” Let me offer you a justification: I &lt;span class=&quot;caps&quot;&gt;WANT&lt;/span&gt; TO &lt;span class=&quot;caps&quot;&gt;FIND&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;BUGS&lt;/span&gt;. :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: Now now, changing the definition of a term on me constitutes dirty pool. Stop that! :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: When you say ‘Presumably, we have tests that intend to test step 2, which justifiably fail’ I would say that sounds like a dangerous presumption. Just because we write a test, and that test has a purpose, does not mean the test achieves its purpose. In fact, as far as we know a test &lt;span class=&quot;caps&quot;&gt;NEVER&lt;/span&gt; achieves its deeper purpose of finding all possible interesting bugs in the thing it is testing. Of course, when I test, I want to find all interesting bugs, and of course, I will never know that I have found all of them worth finding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: I think you’ve taken my specific definition of “justifiable failure” and extended it past how I chose to use the term. When I write a test that fails because of a defect in the code that test intends to focus on, then I call that failure justifiable. All other failures are not justifiable. As a result, the statement you zeroed in on appears tautological to me… except my sloppy use of “presumably”. Let me clarify what I left unexpressed. Let’s assume that we have used integration tests to test the five-step process minimally broadly (in other words, we have written tests to find at least all basic correctness defects). That means that we’ve written some tests specifically to check step 2. Suppose now the existence of a defect in only step 2. When our test for step 4 fails because of the defect in step 2, the tests for step 2 fail justifiably, while the tests for step 4 fail unjustifiably. I haven’t yet turned my attention to latent and lurking defects, for the reason I provide at the end of this comment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: … That’s why I use a diversified test strategy. It seems to me that complicated integration tests that cover ground also covered in other tests is a reasonable strategy— as long as it is not too expenses to produce or maintain. There is a cost/benefit that must be weighed against an opportunity cost, of course.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: I agree; however, I see too many programmers (in particular) using integration tests to help them find or avoid defects that much less expensive isolated object tests would better help them find or avoid. I center my entire argument on the thesis that too many programmers use these tests in a way that leads to considerable wasted effort in maintenance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: So, perhaps you are talking about a restricted context where its not worth the effort of testing a particular function indirectly. Maybe not, but I bet it’s worth considering that sort of testing. Personally, I like automation that touches a lot of things in a lot of places, as long as I can create and maintain it without too much disruption of my sapient testing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: Indeed so! I have wanted to reveal these points gradually so as to avoid writing 20,000 words at once, but I limit the arguments in this series to a specific context: programmers writing tests to show the basic correctness of their code. By &lt;em&gt;basic correctness&lt;/em&gt; I refer to the myth of perfect technology: if I ran the system on perfect technology, would it (eventually) compute the right answer every time? I would call such a system &lt;em&gt;entirely basically correct&lt;/em&gt;. While integration tests offer value in other contexts, too many programmers use them to show basic correctness, and when they do that they waste a tremendous amount of time and effort.&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Jul 2009 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/interlude-basic-correctness</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/interlude-basic-correctness</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Part 3: The Risks Associated with Lengthy Tests</title>
        <description>&lt;p&gt;I just read a tweet from Dale Emery that turned my attention back to the topic of integration tests and their scamminess.&lt;/p&gt;
&lt;p&gt;[Tweet disappeared, courtesy of Tweetpaste. I don’t have a link to the original any more. I apologise for that.]&lt;/p&gt;
&lt;p&gt;Since practitioners tend to write acceptance tests as end-to-end (or integration) tests, I think I can safely substitute the phrase “integration tests” here for “acceptance tests” and retain the essence of Dale’s meaning. I do this because I don’t want you to conclude from what I plan to write that I treat acceptance tests with the same disdain as I treat integration tests. I already went through that when Eric Lefevre-Ardant introduced us to &lt;a href=&quot;https://agile2009.wordpress.com/2009/07/13/meet-david-agile-developer/&quot;&gt;David, Agile Developer&lt;/a&gt;, one of the personas that the Agile 200x conference has developed to help people choose sessions at the conference. While I felt flattered that he chose my session as one to attend, he accidentally misnamed it “Acceptance Tests Are A Scam”, which set off a miniature firestorm in Twitterland. In short: I like acceptance tests when we write them to confirm the presence of a feature; and I dislike them when programmers write integration tests, checking the design and behavior of large parts of the system, and call them “acceptance tests” to justify their existence.&lt;/p&gt;
&lt;p&gt;Back to Dale’s question, which I paraphrase: how often do we write faulty integration tests, meaning that the test failure points to an error in the test, rather than in the production code? Rather than attempt to answer that question, I prefer to write about a strongly related idea: integration tests &lt;em&gt;necessarily&lt;/em&gt; fail more frequently and in a more costly manner than isolated object tests, even when the underlying production code behaves as expected. To simplify the discourse a bit, let me introduce the term &lt;em&gt;unjustifiable test failure&lt;/em&gt; to mean a test failure without a corresponding defect in the production code. When an incorrect test fails, I will call that failure unjustifiable.&lt;/p&gt;
&lt;h2 id=&quot;the-cost-of-unjustifiable-test-failures&quot;&gt;The cost of unjustifiable test failures&lt;/h2&gt;
&lt;p&gt;An unjustifiable failure has both a clear cost an a hidden cost. We know the immediate, clear cost: an unjustifiable failure causes me to do root cause analysis on a nonexistent failure, which costs me something and gains me nothing. More insidious, though, persistent false failures erode my confidence in the tests. I tend to value the tests less. I run them less frequently, reducing the actual value I get from the resulting feedback. With less feedback comes less confidence in the code, and more conservative behavior. I change the code less frequently; I avoid extensive changes, even when they seem appropriate; I entertain fewer ideas because I can’t as easily predict the cost of the corresponding changes. I start designing not to lose, rather than designing to win. I can’t quantify that cost on a given project, but I know it in my heart and we could measure it over time. I think one should eliminate unjustifiable test failures where possible, or at least where easy, and integration tests simply cause an avoidably large number of unjustifiable failures.&lt;/p&gt;
&lt;h2 id=&quot;integration-tests-fail-unjustifiably-more-frequently&quot;&gt;Integration tests fail unjustifiably more frequently&lt;/h2&gt;
&lt;p&gt;Let me support this conjecture with two key arguments.&lt;/p&gt;
&lt;p&gt;First, integration tests tend to require more lines of code than isolated object tests. Perhaps more formally, as we write more integration tests and more isolated object tests in a system, the average length of the integration tests becomes considerably larger—at least double—than the average length of the corresponding isolated object test. If we accept this premise, then combine it with the well-accepted premise that more code means more defects &lt;em&gt;in general&lt;/em&gt;, then it follows directly that integration tests tend to have more defects than isolated object tests. This means that integration tests fail unjustifiably more frequently than isolated object tests.&lt;/p&gt;
&lt;p&gt;Next, because integration tests rely on the correctness of more than one object, it follows directly that a defect in an object results in more integration test failures as compared to the number of failures in corresponding isolated object tests. That production defect, then, results in two classes of test failures: justifiable ones in tests designed to verify the defective behavior, and unjustifiable ones in tests design to verify another behavior, but that happen to execute the defective code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can envision an example of the latter case by thinking of an integration test that verifies a specific alternate path in step 4 of a 5-step process. This test must execute steps 1 through 3 of the process in order to execute step 4, so if we have a defect in step 2 of the process, then this test fails unjustifiably, because it does not actively try to verify step 2. While the test failure can be justified by a defect in step 2, I call the failure &lt;em&gt;unjustifiable with respect to the behavior under test&lt;/em&gt;, because this test does not deliberately attempt to test step 2. Presumably, we have tests that intend to test step 2, which justifiably fail.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Integration tests, then, result in unjustifiable failures by executing some potentially defective behavior without intending to verify it. While I wouldn’t call this a defect in the test, the test nevertheless fails unjustifiably.&lt;/p&gt;
&lt;p&gt;I have tried here to describe the problem of unjustifiable test failures and to explain how integration tests necessarily result in more unjustifiable test failures than isolated object tests. I admit that I have not compared the cost of these unjustifiable test failures to the corresponding costs of writing isolated object tests. I cannot hope to complete a thorough quantitative study on the matter. Instead, I simply want to raise the issues, make some conjectures, reason well about them, then let the reader decide. I have decided to write more isolated object tests and fewer integration tests unless I find myself in a drastically different context than the ones I’ve seen over the past decade or so.&lt;/p&gt;
</description>
        <pubDate>Mon, 20 Jul 2009 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/part-3-the-risks-associated-with-lengthy-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/part-3-the-risks-associated-with-lengthy-tests</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Part 2: Some Hidden Costs of Integrated Tests</title>
        <description>&lt;blockquote&gt;
&lt;p&gt;I fear that this first article in the series may be attacking a view that very few people hold: the idea that one should test all code paths by integration testing alone. — Dan Fabulich&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I tell &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; practitioners &lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;my opinion about integrated tests&lt;/a&gt;, some treat my position as a straw man. They point out that “no one” seriously tries to test entire systems exclusively with integrated tests. While I understand their reaction, I need to point out that I never made that claim. I see far more damaging behavior in teams that practise &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;: they duplicate a sizable amount of their effort by designing their objects with thorough focused tests, then adding a suite of integrated tests that verify a substantial amount of the same behavior. I understand why they do it. I used to do it. And I want them to stop.&lt;/p&gt;
&lt;p&gt;Every integrated test costs… well, I don’t know how to accurately say how much it costs. After computing the superficial cost of writing and maintaining the test, I quickly lose track of the varying effects of writing integrated tests in place of, or even in addition to, focused object tests. I can compute the raw execution time tax on integrated tests: an average focused test executes in 4 ms, while an average integrated tests takes closer to 100 ms. I feel comfortable estimating the difference at a more conservative order of magnitude base 10. Beyond that, I find myself lost in the implications of writing integrated tests to form a clear picture of the cost. Let me give you an idea of what I mean.&lt;/p&gt;
&lt;h1 id=&quot;a-tale-of-two-test-suites&quot;&gt;A Tale of Two Test Suites&lt;/h1&gt;
&lt;p&gt;Consider two test suites. One executes in 6 seconds, and the other in 1 minute. Pretend they cover the same code equally well. I mean that they have the same power to uncover mistakes in the system. Now imagine yourself writing code and executing the 6-second suite. You make a handful of edits, then you run the tests. What do you do for 6 seconds? You predict the outcome of the test run: they will all pass, or the new test will fail because you’ve just written it, or the new test might pass because you think you wrote too much code to pass a test 10 minutes ago. In that span of time, you have your result: the tests all pass, so now you refactor. You probably needed about 6 seconds to read up to here.&lt;/p&gt;
&lt;p&gt;Now imagine you run the 1-minute test suite. Once again, you predict the result, during which time 6 seconds pass. If you work alone, then after 8 seconds you’ve started drumming your fingers on the desk or letting your eyes dart around the room. You notice the long list of tasks on the team task board. You start to feel your stomach rumble, noticing the time: 11:42. Time for lunch soon. You wonder what the cantina has for lunch, so you point your browser at their intranet site. Tilapia sounds good. You wonder whether Lisa will join you for lunch, so you switch to your email client. Before you write her, you notice a notification to pay your credit card bill. You can do that in 30 seconds, so you switch back to your browser to log in to online banking and quickly make a payment. It turns out Lisa has a lunch meeting, and you reconsider your choice of fish. Today, you decide, feels like a burger day. In the time you imagined yourself doing that, assuming you guessed how long it took to actually do what you imagined, over 1 minute passed. The computer has spent valuable computing time waiting for you.&lt;/p&gt;
&lt;p&gt;Pairing doesn’t seem to solve this problem. If you ran this test suite during a pair-programming session, then you probably spent time chatting. At first, you discussed the recent test. After a while, you discussed the task. That killed about 40 seconds, so you started drifting to other topics: the weekend, the kids, XBox, Battlestar Galactica, baseball, management… then you turned around to notice the test run finished while you were arguing whether Cliff Lee deserved the Cy Young award. I don’t mind injecting plenty of relaxed conversation into my work, but when waiting repeatedly for a 1-minute test suite it doesn’t take long to run out of things to talk about.&lt;/p&gt;
&lt;p&gt;I need to point out the dual cost here. The first, we can easily see and measure: the time we spend waiting for the tests plus the time the computer waits for us, because we find it hard to stare at the test runner for 60 seconds and react to it immediately after it finishes. I don’t care much about that cost. I care about the visible but highly unquantifiable cost of losing focus.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; works well for me in large part because it helps me focus. When I write a test, I clarify my immediate goal, focus on making it pass, then focus on integrating that work more appropriately into the design. I get to do this in short cycles that demand sustained focus and allow brief recovery&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. This cycle of focus and recovery builds rhythm and this rhythm builds momentum. This helps lead to the commonly-cited and powerful state of flow. A 6-second test run provides a moment to recover from exertion; whereas a 1-minute test run disrupts flow. It acts like an annoying short interruption every few minutes. We can try to measure the cumulative effect of these interruptions, but I guess you can imagine a day, possibly a recent one, when periodic short interruptions made it nearly impossible for you to concentrate. How productive did you feel that day? How much did you achieve? How much pressure did you feel to catch up the next day? How relaxed did you feel that evening at home? Did you enjoy dinner? Did you feel present for your spouse or kids or pets? How well did you sleep? How refreshed did you feel the next morning?&lt;/p&gt;
&lt;p&gt;Among the early &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; literature I distinctly remember reading that practising &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; would help me focus, relax, achieve more and feel better at the end of a task. I remember agonizing over integrated tests. Teams call me expressly to learn how to tame big, slow, brittle test suites. They don’t call me when they feel focused, relaxed and productive. I tell you: &lt;strong&gt;integrated tests will slowly kill you&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id=&quot;so-what-now&quot;&gt;So What Now?&lt;/h1&gt;
&lt;p&gt;But you have integrated tests now, and you haven’t yet learned about the alternatives. How can you cope with your reality? You could regain your focus by running the most important 10% of those tests. That would take 6 seconds and fit into your flow. It also runs a substantial risk of failure. You’ve experienced this. Remember the last time you changed a line of code in one part of the system and it broke something way over there in another module? How did you feel when that happened? How long did you spend tracking down a mistake in some arcane part of they system that perhaps no one understands? How did you deal with having to branch your code changes to deal with the bigger problem? How many times have you told your wild goose chase story to your fellow programmers? How long did you need to recover before returning to a decent state of flow while working on your original task?&lt;/p&gt;
&lt;p&gt;So it appears you have a choice between frequent annoying disruptions and less frequent but comparatively catastrophic disruptions. A Morton’s Fork you can blame squarely on integrated tests. Stop writing them.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Jim Loehr and Tony Schwartz, &lt;a href=&quot;https://link.jbrains.ca/14pM4CJ&quot;&gt;&lt;em&gt;The Power of Full Engagement&lt;/em&gt;&lt;/a&gt;. This book significantly changed my attitude towards managing work—for the much, much better.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;For more about the focus/recovery cycle, I highly recommend &lt;a href=&quot;#references&quot;&gt;The Power of Full Engagement&lt;/a&gt;&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Wed, 08 Apr 2009 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/part-2-some-hidden-costs-of-integrated-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/part-2-some-hidden-costs-of-integrated-tests</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</title>
        <description>&lt;section class=&quot;aside&quot;&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;. It’s 2023 and although I still broadly agree with the &lt;em&gt;content&lt;/em&gt; of this article, I don’t like the &lt;em&gt;style&lt;/em&gt; of it any more. I find it too abrasive and judgmental. I’m sorry about that.&lt;/p&gt;
&lt;p&gt;I leave this article here because I’m not ready to rewrite it just yet. I almost certainly will, although I haven’t decided when to do that. In the meantime, I’ve changed the title of this post to reflect my current thinking, even though I imagine that many readers will always refer to think as “Integrated (even Integration!) Tests Are A Scam”. Popular names change slowly; I don’t mind.&lt;/p&gt;
&lt;p&gt;Integrated tests won’t kill you, although the &lt;em&gt;scam&lt;/em&gt; remains a problem. Nowadays it has become worse as many distributed “microservices” architectures exhibit the same symptoms while adding the cost of having published APIs, thereby restricting their ability to refactor. If you thought refactoring with &lt;em&gt;mock objects&lt;/em&gt; was hard…!&lt;/p&gt;
&lt;p&gt;I don’t &lt;em&gt;hate&lt;/em&gt; integrated tests, but neither do I trust them. The theatrics in this article came at a time when I thought I needed to yell loudly and provocatively in order for people to listen. I wanted to capture their attention and I was playing around with some marketing/branding ideas. I don’t want to rewrite history, but rest assured that I present these ideas with a much more moderate tone these days.&lt;/p&gt;
&lt;p&gt;In other words, please don’t let the abrasive and judgmental tone get in the way of whichever good ideas are still in here. One day I’ll find the energy to write this again from the beginning in a style that reflects the more-moderate me. But the integrated tests scam will almost certainly still be a problem, whenever I finally sit down to do that. I still believe that.&lt;/p&gt;
&lt;/section&gt;
&lt;p style=&quot;font-size: small; font-style: italic;&quot;&gt;
On March 1, 2010 I changed the phrase “integration tests” to “integrated tests” in this article.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Integrated tests are a scam—a self-replicating virus that threatens to infect your code base, your project, and your team with endless pain and suffering.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Wait… &lt;em&gt;what?&lt;/em&gt;
&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;
Would you prefer to watch a video? &lt;a href=&quot;https://www.youtube.com/watch?v=fhFa4tkFUFw&amp;t=13s&quot;&gt;Watch 53 minutes of video on YouTube with no tracking code&lt;/a&gt;
&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;
&lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;Read more in this series&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Integrated tests pose a significant risk to the health of your code base. If you’re not careful, accumulating integrated tests will gradually suffocate your code base, driving you to a place where you have to decide whether it would be cheaper to throw all your tests away and try again. Nobody should have to face that choice.
&lt;/p&gt;
&lt;p&gt;
Of course, I should clarify what I mean by &lt;em&gt;integrated tests&lt;/em&gt;, because, like any term in software, we probably don’t agree on a meaning for it.
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
I use the term &lt;em&gt;integrated test&lt;/em&gt; to mean any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I, too, would prefer a more rigorous definition, but this one works well for most code bases most of the time. I have a simple point: I generally don’t want to rely on tests that might fail for a variety of reasons. Those tests create more problems than they solve.
&lt;/p&gt;
&lt;p&gt;
You write integrated tests because you can’t write perfect unit tests. You know this problem: all your unit tests pass, but someone finds a defect anyway. Sometimes you can explain this by finding an obvious unit test you simply missed, but sometimes you can’t. In those cases, you decide you need to write an integrated test to make sure that all the production implementations you use in the broken code path now work correctly together.
&lt;/p&gt;
&lt;p&gt;
So far, no big deal, but you’ll meet the monster as soon as you think this:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
If we can find defects even when our tests pass 100%, and if I can only plug the hole with an integrated tests, then &lt;em&gt;we’d better write integrated tests everywhere&lt;/em&gt;.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Bad idea. Really bad.
&lt;/p&gt;
&lt;p&gt;
&lt;img src=&quot;/images/explosion-1310556-640w.jpg&quot; style=&quot;width: 80%&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
Why so bad? A little bit of simple arithmetic should help explain.
&lt;/p&gt;
&lt;p&gt;
You have a medium-sized web application with around 20 pages, maybe 10 of which have forms. Each form has an average of 5 fields and the average field needs 3 tests to verify thoroughly. Your architecture has about 10 layers, including web presentation widgets, web presentation pages, abstract presentation, an &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; bridge to your service &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, controllers, transaction scripts, abstract data repositories, data repository implementations, &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; statement mapping, &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; execution, and application configuration. A typical request/response cycle creates a stack trace 30 frames deep, some of which you wrote, and some of which you’ve taken off the shelf from a wide variety of open source and commercial packages. How many tests do you need to test this application &lt;em&gt;thoroughly&lt;/em&gt;?
&lt;/p&gt;
&lt;p&gt;
At least 10,000. Maybe a million. &lt;em&gt;One million&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://tinyurl.com/dx68z4&quot;&gt;&lt;em&gt;Wie ist es möglich?!&lt;/em&gt;&lt;/a&gt; Consider 10 layers with 3 potential branch points at each layer. Number of code paths: 3&lt;sup&gt;10&lt;/sup&gt; &amp;gt; 59,000. How about 4 branch points per layer? 4&lt;sup&gt;10&lt;/sup&gt; &amp;gt; 1,000,000. How about 3 branch and 12 layers? 3&lt;sup&gt;12&lt;/sup&gt; &amp;gt; 530,000.
&lt;/p&gt;
&lt;p&gt;
Even if one of your 12 layers has a single code path, 3&lt;sup&gt;11&lt;/sup&gt; &amp;gt; 177,000.
&lt;/p&gt;
&lt;p&gt;
Even if your 10-layer application has only an average of 3.5 code paths per layer, 3.5&lt;sup&gt;10&lt;/sup&gt; &amp;gt; 275,000&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn6d7a96adc995137445819fd95bd31a74367d9f83&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;
&lt;p&gt;
To simplify the arithmetic, suppose you need &lt;em&gt;only&lt;/em&gt; 100,000 integrated tests to cover your application. Integrated tests typically touch the file system or a network connection, meaning that they run on average at a rate of no more than 50 tests per second. Your 100,000-test integrated test suite executes in 2000 seconds or 34 minutes. That means that you execute your entire test suite only when you feel ready to check in. Some teams let their continuous build execute those tests, and hope for the best, wasting valuable time when the build fails and they need to backtrack an hour.
&lt;/p&gt;
&lt;p&gt;
How long do you need to &lt;em&gt;write&lt;/em&gt; 100,000 tests? If it takes 10 minutes to write each test—that includes thinking time, time futzing around with the test to make it pass the first time, and time maintaining your test database, test web server, test application server, and so on—then you need 2,778 six-hour human-days (or pair-days if you program in pairs). That works out to 556 five-day human-weeks (or pair-weeks).
&lt;/p&gt;
&lt;p&gt;
Even if I overestimate by a factor of five, you still need two full-time integrated test writers for a one-year project &lt;em&gt;and&lt;/em&gt; a steady enough flow of work to keep them busy six hours per day &lt;em&gt;and&lt;/em&gt; you can’t get any of it wrong, because you have no time to rewrite those tests.
&lt;/p&gt;
&lt;p&gt;
No. You’ll have those integrated test writers writing production code by week eight.
&lt;/p&gt;
&lt;p&gt;
Since you won’t write all those tests, you’ll write the tests you can. You’ll write the happy path tests and a few error cases. You won’t check all ten fields in a form. You won’t check what happens on February 29. You’ll jam in a database change rather than copy and paste the 70 tests you need to check it thoroughly. You’ll write around 50 tests per week, which translates to 2,500 tests in a one-year project. Not 100,000.
&lt;/p&gt;
&lt;p&gt;
2.5% of the number you need to test your application thoroughly.
&lt;/p&gt;
&lt;p&gt;
Even if you wrote the most important 2.5%, recognizing the nearly endless duplication in the full complement of tests, you’d cover somewhere between 10% and 80% of your code paths, and you’ll have no idea whether you got closer to 10% or 80% until your customers start pounding the first release.
&lt;/p&gt;
&lt;p&gt;
Do you feel lucky? Well, do you?&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;p&gt;
So you write your 2,500 integrated tests. Perhaps you even write 5,000 of them. When your customer finds a defect, how will you fix it? Yes: with another handful of integrated tests. The more integrated tests you write, the more of a false sense of security you feel. (Remember, you just increased your code path coverage from 5% to 5.01% with those ten integrated tests.) This false sense of security helps you feel good about releasing more undertested code to your customers, which means they find more defects, which you fix with yet more integrated tests. Over time your code path coverage &lt;em&gt;decreases&lt;/em&gt; because the complexity of your code base grows more quickly than your capacity to write enough integrated tests to cover it.
&lt;/p&gt;
&lt;p&gt;
…and you wonder why you spend 70% of your time with support calls?
&lt;/p&gt;
&lt;p&gt;
Integrated tests are a scam. Unreliable, self-replicating time-wasters. They have to go.
&lt;/p&gt;
&lt;hr /&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn6d7a96adc995137445819fd95bd31a74367d9f83&quot;&gt;
&lt;sup&gt;1&lt;/sup&gt; True: few code bases distribute their complexity to their layers uniformly. Suppose half your 12 layers have only two branch points—one normal path and one error path—while the others have 5 branch points. 2&lt;sup&gt;6&lt;/sup&gt;·5&lt;sup&gt;6&lt;/sup&gt; = 1,000,000 and for 4 branch points 2&lt;sup&gt;6&lt;/sup&gt;·4&lt;sup&gt;6&lt;/sup&gt; &amp;gt; 262,000. You can’t win this game.
&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn&quot;&gt;
&lt;sup&gt;2&lt;/sup&gt; Aslak Hellesøy points to a way to take luck mostly out of the equation. &lt;a href=&quot;https://www.pairwise.org/&quot;&gt;His technique for choosing high-value tests&lt;/a&gt; will certainly help, but it stops short of testing your code &lt;strong&gt;thoroughly&lt;/strong&gt;. I believe you can achieve truly thorough focused tests with similar cost to writing and maintaining integrated tests even using the pairwise test selection technique. (Thanks, Aslak, for your comment on April 12, 2009.)
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://integrated-tests-are-a-scam.jbrains.ca&quot;&gt;Read more in this series&lt;/a&gt;
&lt;/p&gt;
</description>
        <pubDate>Sun, 05 Apr 2009 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/integrated-tests-are-a-scam</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/integrated-tests-are-a-scam</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>In brief: Contract Tests</title>
        <description>&lt;p&gt;&lt;strong&gt;Contract Tests&lt;/strong&gt; explain how a class should extend a superclass or implement an interface, so that I don’t have to read a bunch of prose to figure out how to do that. Typically, a contract test case class is abstract/deferred/not fully implemented, then I extend/subclass it and implement a Factory method or two to return instances of my own implementation of the given interface. That gives me a standard battery of tests I can run to drive my implementation. It might not be perfect (I’d have &lt;em&gt;n&lt;/em&gt; failing tests to start) but I prefer it to documentation written in prose.&lt;/p&gt;
&lt;p&gt;So if you’re delivering something you want me to extend (like a framework) and I need to follow more than three rules, then please deliver some contract tests along with it.&lt;/p&gt;
</description>
        <pubDate>Wed, 02 Mar 2005 00:00:00 -0400</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/in-brief-contract-tests</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/in-brief-contract-tests</guid>
        
        
        <category>Beware the Integrated Tests Scam (was Integrated Tests Are a Scam)</category>
        
      </item>
    
      <item>
        <title>Persistence Last</title>
        <description>&lt;aside&gt;
&lt;p&gt;I originally wrote this article in 2003, based on experiences I had from 1997-2001 while working at IBM. The original Domain Driven Design website kindly published it for me, but they appear to have since reorganized everything, and the link to the original article had become lost. Kevin Rutherford asked me to find the article, and I didn’t even know where to look at first. Fortunately, I found &lt;em&gt;one tweet&lt;/em&gt; (of mine!) that referred to an otherwise dead link to the previous incarnation of this blog. The internet sometimes amazes me in its resilience.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;I was working at IBM when I discovered JUnit, Design Patterns, &lt;a href=&quot;#references&quot;&gt;&lt;em&gt;Refactoring&lt;/em&gt;&lt;/a&gt; and &lt;a href=&quot;#references&quot;&gt;&lt;em&gt;Pragmatic Programmer&lt;/em&gt;&lt;/a&gt;. These all gave me a bright idea how to deal with a specific problem in my programming group. There is a database group that acts as gatekeeper to the database schema for our product. Since the product has several hundred tables, I can appreciate the desire for conceptual integrity by having a small group of like minded people oversee its design. Unfortunately, for the most part, the database gatekeepers do not criticize design, rather they merely control change. This change control leads to problems on both sides: sometimes I have to wait five business days for the testing group to see changes; sometimes my changes are “lost in the translation” and made incorrectly by one of the gatekeeper’s teammates. This sets the context for my decision to do something radical: develop the database schema last. It is radical because in that organization, the database was — and may well still be&lt;a href=&quot;#fn1&quot; class=&quot;footnote-ref&quot; id=&quot;fnref1&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; — the center of the universe.&lt;/p&gt;
&lt;p&gt;I built a component entirely decoupled from its persistence mechanism. It was the first time that I wrote code that felt truly object-oriented.&lt;a href=&quot;#fn2&quot; class=&quot;footnote-ref&quot; id=&quot;fnref2&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; Using JUnit to test my business logic led me to use a “dummy” persistence mechanism during testing, and I continued to use this dummy persistence mechanism until I had implemented every feature I needed.&lt;a href=&quot;#fn3&quot; class=&quot;footnote-ref&quot; id=&quot;fnref3&quot; role=&quot;doc-noteref&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; This led me up to approximately three weeks before feature/database schema freeze. As one might expect, this was a period of time during which teams were continually submitting schema changes and during which weekly meetings were used to judge which changes were “in” and which were “out”. These was considerable tension as everyone’s goal was to converge on a final schema. At “freeze minus three weeks” my component was fully built, fully programmer tested, including an entity bean-based implementation of the persistence mechanism. Building this entity bean persistence mechanism led to designing a simple, four-table database schema. &lt;strong&gt;I designed the database schema only after all the business features were fully implemented and programmer tested.&lt;/strong&gt; Since I practised test-driven development, “implemented” implied “programmer tested” in this case. At the third-last meeting [of the &lt;a href=&quot;#references&quot;&gt;Change Control Board&lt;/a&gt;] I submitted my request for new database tables. In response to complaints that I was bringing this up “awfully late in the cycle” I stated with supreme confidence, “Yes. To compensate you for this, I relinquish all change requests for the rest of the release. If I feel I need a schema change, I will simply have to deal with it myself somehow.” The database group hesitated, but felt that they had little choice: without the schema I proposed, there was no way to ship my feature set. They agreed.&lt;/p&gt;
&lt;p&gt;As I promised, I changed absolutely no part of that database schema. While other groups were scrambling to make last-minute changes, I sat back, relaxed and grinned. Of course, while they were also scrambling to fix defects that the testing group reported, I also sat back, relaxed and grinned. I did have to fix one defect, but that was a misunderstood requirement, rather than an incorrectly-implemented feature. I attribute this success to two main techniques: programmer testing and letting the domain drive the database schema.&lt;/p&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;
&lt;p&gt;This was the second of two experiences from my early programming career that informed my opinions about programmer testing and the role of test doubles. Although I don’t remember doing this work in the now-called Mockist style, it was the first time that I decoupled persistence from the domain model (such as it was) and understood the difference between using test doubles for technology dependencies (JDBC in this case) and using them one level higher in the call stack to separate the Repository abstraction from the rest of the system. It was the first time that I really tried “not mocking types that I didn’t own”. It worked well!&lt;/p&gt;
&lt;p&gt;This episode contributed considerably to my advocacy for programmer testing, test doubles, and eventually test-first programming, evolutionary design, and test-driven development. Without it, I would not be writing these words today.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;Steve Freeman, Nat Pryce, Tim Mackinnon, Joe Walnes, &lt;a href=&quot;https://www.jmock.org/oopsla2004.pdf&quot;&gt;“Mock Roles, Not Types”&lt;/a&gt;. The programming episode that I describe here amounted to applying the principles of this paper to my design, using test doubles for the Repository and not the database client library.&lt;/p&gt;
&lt;p&gt;Martin Fowler and others, &lt;a href=&quot;https://link.jbrains.ca/32ZLFJJ&quot;&gt;&lt;em&gt;Refactoring: Improving the Design of Existing Code&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Gang of Four. &lt;a href=&quot;https://link.jbrains.ca/11ATEqK&quot;&gt;&lt;em&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/em&gt;&lt;/a&gt;. The original reference for a description of the Abstract Factory pattern.&lt;/p&gt;
&lt;p&gt;Andrew Hunt and Dave Thomas, &lt;a href=&quot;https://link.jbrains.ca/WNg8Se&quot;&gt;&lt;em&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/em&gt;&lt;/a&gt;. Still one of those classics that demands a place on every programmer’s bookshelf.&lt;/p&gt;
&lt;p&gt;Steve McConnell, &lt;a href=&quot;https://link.jbrains.ca/1QzMlux&quot;&gt;&lt;em&gt;Rapid Development: Taming Wild Software Schedules&lt;/em&gt;&lt;/a&gt;. The book that includes, among other things, the Change Control Board as one of its “blue-ribbon practices”, McConnell’s version of a “best practice”.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I originally wrote this line in 2003, thinking back to 2000. I don’t think I would change this line at all, even today. On the contrary, &lt;em&gt;the database&lt;/em&gt; has become even more of the center of the universe in many (most?) of the codebases I’ve seen in the nearly 20 years since.&lt;a href=&quot;#fnref1&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;I forgive myself for saying something like this, even though I probably meant “modular” and not “object-oriented”. I probably meant “with a non-zero amount of abstraction”, as opposed to the typical open, obsessed-with-details “design” that I’ve seen in myriad codebases since.&lt;a href=&quot;#fnref2&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id=&quot;fn3&quot; role=&quot;doc-endnote&quot;&gt;&lt;p&gt;We would now recognize this as using test doubles for the Repository layer.&lt;a href=&quot;#fnref3&quot; class=&quot;footnote-back&quot; role=&quot;doc-backlink&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
        <pubDate>Tue, 01 Jul 2003 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/persistence-last</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/persistence-last</guid>
        
        
      </item>
    
      <item>
        <title>JUnit: A Starter Guide</title>
        <description>&lt;p&gt;
Not long after the Christmas break between 2001 and 2002 I wrote “JUnit: A Starter Guide” in response to a flurry of complaints over the lack of a decent JUnit tutorial. I didn’t know at the time that I would turn this simple tutorial, written somewhat in haste, into &lt;em&gt;JUnit Recipes: Practical Methods for Programmer Testing&lt;/em&gt;, which I completed in 2004. It has surprised me to note that several hundred people continue to read the Starter Guide, so I thought I would include a link to it from here. In order not to deal with differences in &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; formatting, I have decided to link to the document as a &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; and keep it mostly for historical purposes. Much has changed since 2002, and I hope the Starter Guide remains a solid introduction to JUnit, test-driven development and software design.
&lt;/p&gt;
&lt;div&gt;
&lt;img style=&quot;float: left; width: 64px; padding-right: 10px&quot; src=&quot;/images/download-pdf-64w.png&quot;&gt;&lt;/img&gt;
&lt;p style=&quot;margin-top: auto; margin-bottom: auto&quot;&gt;
&lt;a href=&quot;https://articles.jbrains.ca/JUnitAStarterGuide.pdf&quot; title=&quot;pdf&quot;&gt;JUnit: A Starter Guide&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 01 Jun 2001 00:00:00 -0300</pubDate>
        <link>https://blog.thecodewhisperer.com/permalink/junit-a-starter-guide</link>
        <guid isPermaLink="true">https://blog.thecodewhisperer.com/permalink/junit-a-starter-guide</guid>
        
        
      </item>
    
  </channel>
</rss>
