<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Cleaner Code - Learn TDD, Clean Architecture & Craftsmanship without the Headaches]]></title><description><![CDATA[A blog for devs who care about writing clean code. We will walk you through TDD, share cool (free) resources, and chat about clean architecture. No BS, just practical stuff. Make yourself at home!]]></description><link>https://blog.cleaner-code.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1744388023840/e218106b-0610-4132-bec4-92ca882dead5.png</url><title>Cleaner Code - Learn TDD, Clean Architecture &amp; Craftsmanship without the Headaches</title><link>https://blog.cleaner-code.com</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 02:57:56 GMT</lastBuildDate><atom:link href="https://blog.cleaner-code.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[[Ebook][EN/FR] Code Culture]]></title><description><![CDATA[Description [EN]:Code Culture is one of the whitepapers published by Octo Technology. It’s available for free and offers tons of practical advice to help you get familiar with Software Craftsmanship.
You'll find clear explanations about Test-Driven D...]]></description><link>https://blog.cleaner-code.com/ebookenfr-code-culture</link><guid isPermaLink="true">https://blog.cleaner-code.com/ebookenfr-code-culture</guid><category><![CDATA[ebook]]></category><category><![CDATA[free]]></category><category><![CDATA[TDD (Test-driven development)]]></category><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[craftsmanship]]></category><category><![CDATA[techlead]]></category><category><![CDATA[code review]]></category><category><![CDATA[Code Quality]]></category><dc:creator><![CDATA[Evyweb]]></dc:creator><pubDate>Tue, 15 Apr 2025 21:23:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744751833855/137ddc5f-cb43-4abf-ad69-b087dff644de.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Description [EN]:</strong><br /><strong>Code Culture</strong> is one of the whitepapers published by <strong>Octo Technology</strong>. It’s available for free and offers tons of practical advice to help you get familiar with <strong>Software Craftsmanship</strong>.</p>
<p>You'll find clear explanations about <strong>Test-Driven Development</strong>, <strong>Code Reviews</strong>, <strong>Technical Debt</strong>, the <strong>Tech Lead</strong> role, and how to apply these concepts within your company.</p>
<p>It’s beginner-friendly, easy to read, and super useful. Enjoy!</p>
<p><strong>Language:</strong><br />English</p>
<p><strong>How to get it?</strong><br />Just fill out the form with a valid email address, and you’ll receive the download link straight to your inbox.</p>
<p><a target="_blank" href="https://publication.octo.com/en/download-whitepaper-culture-code">https://publication.octo.com/en/download-whitepaper-culture-code</a></p>
<hr />
<p><strong>Description [FR]:</strong><br /><strong>Culture Code</strong>, c’est un livre blanc publié par <strong>Octo Technology</strong>. Il est dispo gratuitement et te donne plein de conseils concrets pour te familiariser avec le <strong>Software Craftsmanship</strong>.</p>
<p>Tu y trouveras des explications claires sur le <strong>TDD</strong>, les <strong>Code Reviews</strong>, la <strong>Dette Technique</strong>, le rôle de <strong>Tech Lead</strong>, et comment appliquer tout ça dans ta boîte.</p>
<p>C’est super accessible, facile à lire, et franchement utile. Bonne lecture!</p>
<p><strong>Langue :</strong><br />Français</p>
<p><strong>Comment l’obtenir ?</strong><br />Il te suffit de remplir le formulaire avec une adresse mail valide, et tu recevras directement le lien de téléchargement dans ta boîte mail.</p>
<p>👉 <a target="_blank" href="https://publication.octo.com/fr/telechargement-livre-blanc-culture-code">https://publication.octo.com/fr/telechargement-livre-blanc-culture-code</a></p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744751268487/8a9003d5-d952-4e9e-9e57-7957a8ae0ac8.webp" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[[FR] TDD: Les 3 choses que tu peux tester]]></title><description><![CDATA[Quand tu commences à faire du TDD, c’est normal d’être un peu paumé.Tu ne sais pas trop quoi tester, tu avances à tâtons, et si en plus tu découvres le framework de test en même temps parce que t’en as jamais fait… c’est le combo parfait pour galérer...]]></description><link>https://blog.cleaner-code.com/fr-tdd-les-3-choses-que-tu-peux-tester</link><guid isPermaLink="true">https://blog.cleaner-code.com/fr-tdd-les-3-choses-que-tu-peux-tester</guid><category><![CDATA[TDD (Test-driven development)]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[craftsmanship]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Evyweb]]></dc:creator><pubDate>Mon, 14 Apr 2025 06:36:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744535547183/91e5e807-02b3-4d80-bfa4-95735b6a7010.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Quand tu commences à faire du <strong>TDD</strong>, c’est normal d’être un peu paumé.<br />Tu ne sais pas trop quoi tester, tu avances à tâtons, et si en plus tu découvres le framework de test en même temps parce que t’en as jamais fait… c’est le combo parfait pour galérer pendant plusieurs heures.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401320826/ed6b1110-e865-4413-b912-7beb0394b702.png" alt /></p>
<p>Mais y’a des petits trucs simples à retenir qui peuvent t'aider. Ça va pas régler tous tes soucis, certes, mais ça peut clairement te débloquer quand tu ne sais pas trop par où commencer.</p>
<p>Parce qu’au fond, si tu prends deux secondes pour y penser, <strong>à part quelques cas très particuliers (tests de perf, de sécu, etc.)</strong>, y’a que trois manières de vérifier qu’un bout de code fait ce que tu attends de lui.</p>
<p><s>Pas dix, pas cinquante.</s> Juste trois.</p>
<p>Et une fois que tu as compris ça, tout devient beaucoup plus simple.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Dans cet article, on ne parlera que d’output.</div>
</div>

<h2 id="heading-la-seule-question-a-te-poser">La seule question à te poser</h2>
<p>Commence juste par répondre à cette simple question:</p>
<blockquote>
<p>Est-ce que le résultat que je veux vérifier est <strong>direct</strong>, <strong>indirect</strong> ou une <strong>collaboration</strong>?</p>
</blockquote>
<p>Bon là je vois déjà ta tête:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401401150/16d1949a-013e-4361-8d00-8cb8e1702289.png" alt /></p>
<p>“Oula c’est quoi ces trucs, je comprends rien, laisse tomber…”.</p>
<p>→ T’inquiètes pas on va voir ça ensemble avec des exemples.</p>
<h2 id="heading-direct-output">Direct output</h2>
<p>On commence avec le plus simple. Et ça tombe bien parce que c’est celui que tu vas essayer d’utiliser le plus souvent. C’est aussi celui qui va te paraitre le plus naturel.</p>
<blockquote>
<p>Imagine que le code que tu essaie d’écrire est celui d'une “machine”. On ne sait pas ce qu’il y a à l’intérieur.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401200549/a569b480-a9ee-4a35-a400-cc91a75dc7f1.png" alt /></p>
<blockquote>
<p>Cette machine, tu lui as donné un but. Ici son but est de “<strong>créer une potion à partir d’une herbe</strong>”.</p>
</blockquote>
<p>→ Donc ce que la <code>machine</code> va “<strong>recevoir en entrée</strong>”, ce sont des <code>herb</code>es.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401657523/65261c70-ddba-4535-929f-bad0ffe76ebd.png" alt /></p>
<p>→ Ce qu’elle “renverra en sortie” c’est une <code>potion</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401702577/ec6e7534-3be7-4a16-ba2a-c51a37a9bda6.png" alt /></p>
<p>Si tu traduis ça en test, vu qu’on est en train de faire du TDD, tu pourrais imaginer quelque chose comme ça (avec des <code>strings</code> pour rester simple):</p>
<pre><code class="lang-typescript">it(<span class="hljs-string">'should create a green potion from green herb'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Arrange</span>
    <span class="hljs-keyword">const</span> machine = <span class="hljs-keyword">new</span> Machine();
    <span class="hljs-keyword">const</span> herb = <span class="hljs-string">'green-herb'</span>;

    <span class="hljs-comment">// Act</span>
    <span class="hljs-keyword">const</span> potion = machine.createPotion(herb);

    <span class="hljs-comment">// Assert</span>
    expect(potion).toBe(<span class="hljs-string">'green-potion'</span>);
});
</code></pre>
<p>Tu vois, on retranscrit assez facilement ce qu’on a dit juste au-dessus. On passe une <code>herb</code> en entrée, et en retour on reçoit une <code>potion</code> verte. Le résultat est <strong>direct</strong>.</p>
<p>C’est le cas le plus simple à tester car tu vas pouvoir passer des valeurs différentes en entrée et checker le résultat en sortie assez facilement.</p>
<p>C’est souvent le cas des calculs d'ailleurs.</p>
<p>Quand on calcule la somme de deux nombres, c’est assez naturel de se dire “si je passe <code>1</code> et <code>2</code> en <code>entrée</code>, le <code>result</code> doit être égal à <code>3</code>”.</p>
<pre><code class="lang-typescript">it(<span class="hljs-string">'should make the sum of two numbers'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Arrange</span>
    <span class="hljs-keyword">const</span> a = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">const</span> b = <span class="hljs-number">2</span>;

    <span class="hljs-comment">// Act</span>
    <span class="hljs-keyword">const</span> result = sum(a, b);

    <span class="hljs-comment">// Assert</span>
    expect(result).toBe(<span class="hljs-number">3</span>);
});
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Parfois, t’as même rien à passer en entrée ou tu n’as pas la main sur tes entrées aussi facilement, je sais. Mais on verra ça dans un autre article, ici on se focus uniquement sur l’output.</div>
</div>

<p>Bref, le truc c’est de se dire que, si le code que tu souhaites tester renvoie quelque chose, c’est du “direct output” et c'est <strong>facilement</strong> <strong>testable</strong>.</p>
<h2 id="heading-indirect-output">Indirect output</h2>
<p>Parfois ça peut être un peu plus compliqué. Le résultat peut être disponible mais “ailleurs”. Et donc pour écrire ton test, tu vas devoir prendre en compte cette contrainte toi aussi. Reprenons notre exemple avec une petite subtilité.</p>
<blockquote>
<p>Notre machine est reliée à une lampe qui devient verte quand la potion a bien été créée.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744404470628/7e2d2d2e-9fae-4268-b9a9-b84cbb240e08.png" alt /></p>
<p>Dans notre cas, la lampe est externe à la machine. La machine y accède d’une façon ou d’une autre, et déclenche un changement d’état.</p>
<p>Comment elle fait? On s’en fiche, tout ce qu’on sait c’est que la machine ne “<strong>renvoie pas</strong>” une lampe en sortie… C’est donc un “<strong>indirect output</strong>”.</p>
<p>Si tu traduits ça en test, une solution possible serait:</p>
<pre><code class="lang-typescript">it(<span class="hljs-string">'should change the color of the lamp to green'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Arrange</span>
    <span class="hljs-keyword">const</span> lamp = <span class="hljs-keyword">new</span> Lamp();
    <span class="hljs-keyword">const</span> machine = <span class="hljs-keyword">new</span> Machine(lamp);
    <span class="hljs-keyword">const</span> herb = <span class="hljs-string">'green'</span>;

    <span class="hljs-comment">// Act</span>
    machine.createPotion(herb);

    <span class="hljs-comment">// Assert</span>
    expect(lamp.color).toBe(<span class="hljs-string">'green'</span>);
});
</code></pre>
<p>On lit facilement que la <code>machine</code> a accès à la <code>lamp</code>, et qu’après avoir créé la <code>potion</code>, la <code>lamp</code> devient verte.</p>
<p>Mais contrairement à la version <code>direct output</code>, ça demande une petite gymnastique mentale en plus.</p>
<p>Et voilà pour notre <strong>deuxième façon de tester</strong>.<br />Encore une dernière, et on a fait le tour.</p>
<h2 id="heading-collaborateurs">Collaborateurs</h2>
<p>Suivant les tests que tu souhaites faire, parfois tu vas vouloir <strong>vérifier que les choses se déroulent exactement comme tu le souhaites</strong>.</p>
<p>Ce ne sera pas un résultat qui sera checké, mais un comportement.<br />On va vouloir vérifier que les acteurs (qu’on va appeler <strong>collaborateurs</strong>) remplissent bien leur rôle comme il faut. Voici un exemple.</p>
<blockquote>
<p>La lampe doit clignotter 3 fois pour avertir qu’une nouvelle potion est prête.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744406064766/8c7f50ef-f28b-4e0f-85af-8db9e89d09ee.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744406073692/a0aca34d-cf95-41aa-81ab-d27f8e356705.png" alt /></p>
<p>Plusieurs choses ici.</p>
<p>Allumer/éteindre une lampe, c’est peut-être long. Ça consomme de l’énergie, ça use l’ampoule.<br />Bref, c’est pas un truc qu’on veut faire pour de vrai en test.<br />Le mieux serait d’utiliser un “test double” ou “doublure de test” en francais pour éviter ces problèmes.</p>
<p>Ce qu’on veut ici, c’est s’assurer que la méthode <code>blink()</code> a bien été appelée 3 fois.</p>
<pre><code class="lang-typescript">it(<span class="hljs-string">'should make the lamp blink 3 times'</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Arrange</span>
    <span class="hljs-keyword">const</span> lamp = <span class="hljs-keyword">new</span> Lamp();
    spyOn(lamp, <span class="hljs-string">'blink'</span>).mockImplementation();    
    <span class="hljs-keyword">const</span> machine = <span class="hljs-keyword">new</span> Machine(lamp);
    <span class="hljs-keyword">const</span> herb = <span class="hljs-string">'green'</span>;

    <span class="hljs-comment">// Act</span>
    machine.createPotion(herb);

    <span class="hljs-comment">// Assert</span>
    expect(lamp.blink).toBeCalledTimes(<span class="hljs-number">3</span>);
});
</code></pre>
<blockquote>
<p>✋ Hophophop! T’as plein de manières de faire des doublures de tests.<br />Ici je retranscrits uniquement ce que nous avons dit au dessus.<br />J’ai utilisé le spyOn avec mockImplementation (dispo dans jest &amp; vitest) dans cet exemple car je pense que tu as déjà dû les rencontrer dans la doc ou des tutos.<br />Mais ce n’est clairement pas la seule facon de faire.<br />On verra notamment comment créer nos propres doublures <strong>sans librairie et les différences entre chaque type de doublure (dummy, stubs, spy, fakes etc…)</strong>. Mais en attendant, on va rester sur cette proposition.</p>
</blockquote>
<p>Ici, tu ne vérifies pas un état mais plutôt que ton collaborateur a bien été sollicité comme prévu pour remplir son job.<br />→ Tu valides donc un <strong>comportement</strong>.</p>
<h2 id="heading-ce-que-tu-dois-retenir">Ce que tu dois retenir</h2>
<p>Quand tu veux écrire un test, demande toi si tu veux vérifier:</p>
<ul>
<li><p>Ce que le code produit (<strong>direct</strong>)</p>
</li>
<li><p>Ce qu'il change ailleurs (<strong>indirect</strong>)</p>
</li>
<li><p>Ce qu'il fait faire aux autres (<strong>collaboration</strong>)</p>
</li>
</ul>
<h2 id="heading-pour-aller-plus-loin">Pour aller plus loin</h2>
<p>Bien entendu les termes ici ont été simplifiés. Mais ça devrait t'aider à y voir plus clair pour écrire tes prochains tests.</p>
<p>Si tu souhaites pousser plus loin, tu peux retrouver tout ça sous les noms:</p>
<ul>
<li><p><strong>Direct</strong> → <em>State Verification</em></p>
</li>
<li><p><strong>Indirect</strong> → <em>Observable Side Effect</em>, <em>Indirect Output</em></p>
</li>
<li><p><strong>Collaboration</strong> → <em>Interaction Testing</em>, <em>Behavior Verification</em></p>
</li>
</ul>
<p>→ Mais t’inquiètes pas, on verra tout ça un peu plus dans les prochains articles.</p>
<p>Voilà quelques livres incontournables sur le TDD (liens d’affiliation Amazon):</p>
<ul>
<li><p><em>xUnit Patterns</em> (Gerard Meszaros): <a target="_blank" href="https://amzn.to/42pw3hZ">https://amzn.to/42pw3hZ</a> - Assez vieux mais l’un des meilleur concernant les patterns de tests</p>
</li>
<li><p><em>TDD by Example</em> (Kent Beck): <a target="_blank" href="https://amzn.to/3YvZu0G">https://amzn.to/3YvZu0G</a></p>
</li>
</ul>
<p>Dans un prochain article, on parlera des inputs directs et indirects donc reste à l'écoute.</p>
]]></content:encoded></item><item><title><![CDATA[[EN] TDD: The 3 things you can test]]></title><description><![CDATA[When you're just starting with TDD, feeling lost is totally normal.You don't really know what you're supposed to test, you're kinda poking around blindly… and if you're learning a test framework at the same time because you've never written a single ...]]></description><link>https://blog.cleaner-code.com/en-tdd-the-3-things-you-can-test</link><guid isPermaLink="true">https://blog.cleaner-code.com/en-tdd-the-3-things-you-can-test</guid><category><![CDATA[TDD (Test-driven development)]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[craftsmanship]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Evyweb]]></dc:creator><pubDate>Mon, 14 Apr 2025 06:33:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744535566227/745ce285-fccd-4af1-8753-765e0fb7d0dc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you're just starting with <strong>TDD</strong>, feeling lost is totally normal.<br />You don't really know what you're supposed to test, you're kinda poking around blindly… and if you're learning a test framework at the same time because you've never written a single test in your life… well, that's the perfect recipe for a few hours of confusion.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401320826/ed6b1110-e865-4413-b912-7beb0394b702.png" alt /></p>
<p>But there are a few simple ideas that can really help.<br />They won’t magically fix everything, but they’ll definitely help you get unstuck when you don’t know where to begin.</p>
<p>Because if you take two seconds to really think about it, <strong>aside from edge cases like perf or security testing</strong>, there are only <strong>three ways</strong> to check that a piece of code is doing what you expect.</p>
<p><s>Not ten. Not fifty.</s> Just <strong>three</strong>.</p>
<p>Once you get that, everything starts to make a lot more sense.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In this article, we will discuss about output checking only.</div>
</div>

<h2 id="heading-the-only-question-you-need-to-ask">The only question you need to ask</h2>
<p>Start by asking yourself this one simple question:</p>
<blockquote>
<p>Is the result I want to verify <strong>direct</strong>, <strong>indirect</strong>, or part of a <strong>collaboration</strong>?</p>
</blockquote>
<p>I can already see your face:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401401150/16d1949a-013e-4361-8d00-8cb8e1702289.png" alt /></p>
<p>“Uhhh what? I have no idea what that means. Nevermind…”</p>
<p>→ Don’t worry. Let’s walk through it together with examples.</p>
<h2 id="heading-1-direct-output">1. Direct output</h2>
<p>Let’s start with the simplest one, and the one you’ll try to use most often.<br />It also happens to feel the most natural.</p>
<blockquote>
<p>Imagine the code you're writing is a "machine".<br />You don't really care what’s going on inside.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401200549/a569b480-a9ee-4a35-a400-cc91a75dc7f1.png" alt /></p>
<blockquote>
<p>That machine has one purpose.<br />In our case: “<strong>create a potion from a herb</strong>”.</p>
</blockquote>
<p>→ So the machine takes an <code>herb</code> as <strong>input</strong>...</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401657523/65261c70-ddba-4535-929f-bad0ffe76ebd.png" alt /></p>
<p>→ ...and gives you a <code>potion</code> as <strong>output</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744401702577/ec6e7534-3be7-4a16-ba2a-c51a37a9bda6.png" alt /></p>
<p>If we translate this into a TDD-style test, you might write something like:</p>
<pre><code class="lang-ts">it(<span class="hljs-string">'should create a green potion from green herb'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Arrange</span>
  <span class="hljs-keyword">const</span> machine = <span class="hljs-keyword">new</span> Machine();
  <span class="hljs-keyword">const</span> herb = <span class="hljs-string">'green-herb'</span>;

  <span class="hljs-comment">// Act</span>
  <span class="hljs-keyword">const</span> potion = machine.createPotion(herb);

  <span class="hljs-comment">// Assert</span>
  expect(potion).toBe(<span class="hljs-string">'green-potion'</span>);
});
</code></pre>
<p>Pretty straightforward, right?</p>
<p>You feed a <code>herb</code> into the machine, and the <strong>return value</strong> is a green <code>potion</code>.</p>
<p>→ That’s a <strong>direct</strong> result.</p>
<p>Direct results are the easiest to test: you pass something in, you get something out, you check the output.</p>
<p>It’s the same with a simple calculation. Let’s say you're writing a <code>sum()</code> function:</p>
<pre><code class="lang-ts">it(<span class="hljs-string">'should make the sum of two numbers'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Arrange</span>
  <span class="hljs-keyword">const</span> a = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">const</span> b = <span class="hljs-number">2</span>;

  <span class="hljs-comment">// Act</span>
  <span class="hljs-keyword">const</span> result = sum(a, b);

  <span class="hljs-comment">// Assert</span>
  expect(result).toBe(<span class="hljs-number">3</span>);
});
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Sometimes, you don’t even need to pass anything as input, or maybe you just don’t have control over the inputs that easily, I know. But we’ll get to that in another article about direct and indirect inputs. For now, we’re focusing only on the <strong>output</strong>.</div>
</div>

<p>In short: <strong>if your code returns a value</strong>, it’s <strong>direct</strong>, and that’s the easiest kind of thing to test.</p>
<h2 id="heading-2-indirect-output">2. Indirect output</h2>
<p>Sometimes things are a bit trickier.<br />The result exists, but it’s visible <strong>somewhere else</strong>, and your test needs to account for that.</p>
<p>Let’s tweak our potion machine example just a bit.</p>
<blockquote>
<p>Our machine is connected to a lamp that turns green when the potion is ready.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744404470628/7e2d2d2e-9fae-4268-b9a9-b84cbb240e08.png" alt /></p>
<p>In this case, the <code>lamp</code> is <strong>external</strong> to the machine.<br />The machine can somehow access it and update its state.</p>
<p>How? Who cares? What matters is that the machine <strong>doesn’t return</strong> the lamp.<br />→ So this is an <strong>indirect</strong> result.</p>
<p>Here’s how that might look in a test:</p>
<pre><code class="lang-ts">it(<span class="hljs-string">'should change the color of the lamp to green'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Arrange</span>
  <span class="hljs-keyword">const</span> lamp = <span class="hljs-keyword">new</span> Lamp();
  <span class="hljs-keyword">const</span> machine = <span class="hljs-keyword">new</span> Machine(lamp);
  <span class="hljs-keyword">const</span> herb = <span class="hljs-string">'green'</span>;

  <span class="hljs-comment">// Act</span>
  machine.createPotion(herb);

  <span class="hljs-comment">// Assert</span>
  expect(lamp.color).toBe(<span class="hljs-string">'green'</span>);
});
</code></pre>
<p>You can clearly see from the test that the <code>machine</code> has access to the <code>lamp</code>, and after creating a <code>potion</code>, the lamp turns green.</p>
<p>It’s still readable and testable, but it’s a little more work than the direct case.</p>
<p>And that’s your <strong>second way</strong> of verifying results. One more to go.</p>
<h2 id="heading-3-collaboration">3. Collaboration</h2>
<p>In some tests, what you want to verify isn’t a result or a state.<br />It’s a <strong>behavior</strong>, something that happened.</p>
<p>You want to check whether the <strong>right thing was done</strong> by a collaborator.</p>
<p>Let’s go back to our potion machine:</p>
<blockquote>
<p>The lamp should blink 3 times to signal that a potion is ready.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744406064766/8c7f50ef-f28b-4e0f-85af-8db9e89d09ee.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744406073692/a0aca34d-cf95-41aa-81ab-d27f8e356705.png" alt /></p>
<p>Now blinking the lamp could take time. It could drain power. Maybe those lightbulbs are expensive.</p>
<p>→ In tests, we want speed, low cost, and predictability.</p>
<p>So the better move is to use a <strong>test double</strong>: a fake object that helps us verify what happened.</p>
<p>We want to <strong>verify</strong> that our <strong>collaborator</strong> <code>lamp</code> had its <code>blink</code> method called exactly 3 times.</p>
<pre><code class="lang-ts">it(<span class="hljs-string">'should make the lamp blink 3 times'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Arrange</span>
  <span class="hljs-keyword">const</span> lamp = <span class="hljs-keyword">new</span> Lamp();
  spyOn(lamp, <span class="hljs-string">'blink'</span>).mockImplementation();    
  <span class="hljs-keyword">const</span> machine = <span class="hljs-keyword">new</span> Machine(lamp);
  <span class="hljs-keyword">const</span> herb = <span class="hljs-string">'green'</span>;

  <span class="hljs-comment">// Act</span>
  machine.createPotion(herb);

  <span class="hljs-comment">// Assert</span>
  expect(lamp.blink).toBeCalledTimes(<span class="hljs-number">3</span>);
});
</code></pre>
<blockquote>
<p>✋ Heads up! There are lots of ways to create test doubles.<br />Here I’m just sticking with what we’ve already discussed.<br />I used <code>spyOn</code> with <code>mockImplementation</code> (from Jest or Vitest) because you’ve probably seen that before in docs or tutorials.<br />But it’s <strong>not</strong> the only way!<br />In a future post, I’ll show how to create your own test doubles <strong>without any library</strong>, and break down the differences between <strong>dummies</strong>, <strong>stubs</strong>, <strong>spies</strong>, <strong>fakes</strong>, and <strong>mocks</strong>.</p>
</blockquote>
<p>So here, you’re not checking a return value or a state.<br />You’re checking that <strong>another element</strong> was <strong>used correctly</strong>.<br />→ That’s what we call verifying a <strong>collaboration</strong>.</p>
<h2 id="heading-tldr">TLDR:</h2>
<p>Whenever you’re about to write a test, just ask:</p>
<ul>
<li><p>What does the code <strong>produce</strong>? → <strong>Direct</strong></p>
</li>
<li><p>What does it <strong>change somewhere else</strong>? → <strong>Indirect</strong></p>
</li>
<li><p>What does it <strong>ask another object to do</strong>? → <strong>Collaboration</strong></p>
</li>
</ul>
<h2 id="heading-want-to-go-deeper">Want to go deeper?</h2>
<p>Obviously, the names I use here are simplified, but this structure will help a ton when you're getting into TDD.</p>
<p>If you want to read more, here are the “official” names for these techniques:</p>
<ul>
<li><p><strong>Direct</strong> → <em>State Verification</em></p>
</li>
<li><p><strong>Indirect</strong> → <em>Observable Side Effect</em>, <em>Indirect Output</em></p>
</li>
<li><p><strong>Collaboration</strong> → <em>Interaction Testing</em>, <em>Behavior Verification</em></p>
</li>
</ul>
<p>Some books if you want to dig in deeper (Amazon affiliate links):</p>
<ul>
<li><p><em>xUnit Patterns</em> (Gerard Meszaros): <a target="_blank" href="https://amzn.to/42pw3hZ">https://amzn.to/42pw3hZ</a> - Old one but great for testing patterns</p>
</li>
<li><p><em>TDD by Example</em> (Kent Beck): <a target="_blank" href="https://amzn.to/3YvZu0G">https://amzn.to/3YvZu0G</a></p>
</li>
</ul>
<p>In an other article, we will discuss about direct and indirect inputs, stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[[Ebook][EN] JavaScript Array Methods]]></title><description><![CDATA[Description [EN]:With this high-quality (and free!) PDF, Todd Motto helps you understand advanced array methods in JavaScript. You'll see both the basics (forEach, map, filter) and more advanced ones like reduce, find, some, or every. Keep it handy, ...]]></description><link>https://blog.cleaner-code.com/ebook-javascript-array-methods-ebook</link><guid isPermaLink="true">https://blog.cleaner-code.com/ebook-javascript-array-methods-ebook</guid><category><![CDATA[ebook]]></category><category><![CDATA[free]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[arrays]]></category><dc:creator><![CDATA[Evyweb]]></dc:creator><pubDate>Fri, 11 Apr 2025 06:44:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744353245468/6bdfddc8-6a7b-4150-9fb8-65a140e22610.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Description [EN]:</strong><br />With this high-quality (and <strong>free</strong>!) PDF, <strong>Todd Motto</strong> helps you understand advanced array methods in <strong>JavaScript</strong>. You'll see both the basics (<code>forEach</code>, <code>map</code>, <code>filter</code>) and more advanced ones like <code>reduce</code>, <code>find</code>, <code>some</code>, or <code>every</code>. Keep it handy, it'll always come in useful!  </p>
<p><strong>Language:</strong><br />English  </p>
<p><strong>How to get it?</strong><br />Just fill out the form on the <strong>website</strong> with a <strong>valid email address</strong>, and you'll <strong>receive the download link</strong> directly <strong>in your inbox</strong>.  </p>
<p>👉 <a target="_blank" href="https://ultimatecourses.com/ebooks/javascript-array-methods">Ultimate Courses - JavaScript Array Methods</a></p>
<hr />
<p><strong>Description [FR]:</strong><br />Avec ce PDF de très grande qualité (et <strong>gratuit</strong>!), <strong>Todd Motto</strong> t’aide à comprendre les méthodes avancées des tableaux en <strong>JavaScript</strong>. Tu verras aussi bien les bases (<code>forEach</code>, <code>map</code>, <code>filter</code>) que des méthodes plus poussées comme <code>reduce</code>, <code>find</code>, <code>some</code> ou <code>every</code>. Garde-le de côté, ça te servira toujours!</p>
<p><strong>Langue</strong>:<br />Anglais</p>
<p><strong>Comment l’obtenir?</strong><br />Il te suffit de remplir le formulaire <strong>sur le site</strong> en indiquant une <strong>adresse mail valide</strong> et tu recevras le <strong>lien de téléchargement directement dans ta boîte mail</strong>.</p>
<p>👉 <a target="_blank" href="https://ultimatecourses.com/ebooks/javascript-array-methods">Ultimate Courses - JavaScript Array Methods</a></p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744351903131/5cd7eaf0-bb5b-44cc-bcaa-6b0de8a4e474.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item></channel></rss>