<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Tech Blog</title>
    <link>https://www.toucantoco.com/en/tech-blog</link>
    <description>The Toucan Toco Tech Team shares its discoveries and hacks. Follow our work and our progress through our testimonials.</description>
    <language>en</language>
    <pubDate>Tue, 23 Sep 2025 15:06:20 GMT</pubDate>
    <dc:date>2025-09-23T15:06:20Z</dc:date>
    <dc:language>en</dc:language>
    <item>
      <title>Youprep: Why it's easier than SQL</title>
      <link>https://www.toucantoco.com/en/tech-blog/youprep-why-its-easier-than-sql</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/youprep-why-its-easier-than-sql" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/youprep_article_banner.jpg" alt="Youprep: Why it's easier than SQL" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Toucan Toco is a Guided Business Analytics solution. It helps large audience of business users to take better decision with clear and simple Data Apps, in various industries around the world.&lt;br&gt;In addition to dashboarding, Toucan provides simplified data preparation features to enable business oriented data transformation for non technical users. &lt;br&gt;As most no-code platforms, Toucan actually began with a “low-code” approach. The journey to “no-code” was full of interesting steps we’d like to share with you today.&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/youprep-why-its-easier-than-sql" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/youprep_article_banner.jpg" alt="Youprep: Why it's easier than SQL" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Toucan Toco is a Guided Business Analytics solution. It helps large audience of business users to take better decision with clear and simple Data Apps, in various industries around the world.&lt;br&gt;In addition to dashboarding, Toucan provides simplified data preparation features to enable business oriented data transformation for non technical users. &lt;br&gt;As most no-code platforms, Toucan actually began with a “low-code” approach. The journey to “no-code” was full of interesting steps we’d like to share with you today.&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Fyouprep-why-its-easier-than-sql&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Wed, 16 Feb 2022 11:09:51 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/youprep-why-its-easier-than-sql</guid>
      <dc:date>2022-02-16T11:09:51Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Bye Bye IE !</title>
      <link>https://www.toucantoco.com/en/tech-blog/tech-blog/bye-bye-ie</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/tech-blog/bye-bye-ie" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Pinata005.gif" alt="Bye Bye IE !" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;In 1998, I was an intern in a small services company. My job was to transcribe a paper documentation in plain HTML for one of their clients. It was dull and boring, but you have to start somewhere…&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/tech-blog/bye-bye-ie" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Pinata005.gif" alt="Bye Bye IE !" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;In 1998, I was an intern in a small services company. My job was to transcribe a paper documentation in plain HTML for one of their clients. It was dull and boring, but you have to start somewhere…&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Ftech-blog%2Fbye-bye-ie&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Fri, 07 Jan 2022 10:04:43 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/tech-blog/bye-bye-ie</guid>
      <dc:date>2022-01-07T10:04:43Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Load testing with k6 and k8s</title>
      <link>https://www.toucantoco.com/en/tech-blog/tech-blog/load-testing-with-k6-and-k8s</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/tech-blog/load-testing-with-k6-and-k8s" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/k6_k8_toucan_large.png" alt="Load testing with k6 and k8s" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Several months ago, we read a really interesting article from Back Market.&amp;nbsp;&lt;a href="https://medium.com/back-market-engineering/how-back-market-sres-prepared-for-black-friday-5f017f343408" title="https://medium.com/back-market-engineering/how-back-market-sres-prepared-for-black-friday-5f017f343408"&gt;The article&lt;/a&gt; describes how the &lt;span&gt;platform&lt;/span&gt;/SRE team prepared and tested their infrastructure &lt;span&gt;for Black Friday, in order&lt;/span&gt; to confirm that they &lt;span&gt;could&lt;/span&gt; handle five times &lt;span&gt;the&lt;/span&gt;ir usual traffic!&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/tech-blog/load-testing-with-k6-and-k8s" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/k6_k8_toucan_large.png" alt="Load testing with k6 and k8s" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Several months ago, we read a really interesting article from Back Market.&amp;nbsp;&lt;a href="https://medium.com/back-market-engineering/how-back-market-sres-prepared-for-black-friday-5f017f343408" title="https://medium.com/back-market-engineering/how-back-market-sres-prepared-for-black-friday-5f017f343408"&gt;The article&lt;/a&gt; describes how the &lt;span&gt;platform&lt;/span&gt;/SRE team prepared and tested their infrastructure &lt;span&gt;for Black Friday, in order&lt;/span&gt; to confirm that they &lt;span&gt;could&lt;/span&gt; handle five times &lt;span&gt;the&lt;/span&gt;ir usual traffic!&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Ftech-blog%2Fload-testing-with-k6-and-k8s&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Tue, 14 Dec 2021 10:12:05 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/tech-blog/load-testing-with-k6-and-k8s</guid>
      <dc:date>2021-12-14T10:12:05Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Our 2021 Q3 Hackathon</title>
      <link>https://www.toucantoco.com/en/tech-blog/2021-q3-hackathon</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/2021-q3-hackathon" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/miniature_hackthon.png" alt="Our 2021 Q3 Hackathon" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Last week was our Hackathon.&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/2021-q3-hackathon" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/miniature_hackthon.png" alt="Our 2021 Q3 Hackathon" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Last week was our Hackathon.&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2F2021-q3-hackathon&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Fri, 05 Nov 2021 10:17:26 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/2021-q3-hackathon</guid>
      <dc:date>2021-11-05T10:17:26Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>6 Reasons to join our Tech Team | Toucan Toco</title>
      <link>https://www.toucantoco.com/en/tech-blog/6-reasons-to-join-our-tech-team</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/6-reasons-to-join-our-tech-team" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/office-2.webp" alt="6 Reasons to join our Tech Team | Toucan Toco" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;div class="post"&gt; 
 &lt;a class="post__back-to-blog" href="https://www.toucantoco.com/en/tech-blog.html"&gt; &lt;/a&gt; 
 &lt;br&gt; 
 &lt;p&gt;I recently asked my team “Why do you like working at Toucan”. And I was amazed at how closely aligned their opinions were on the subject.&lt;/p&gt; 
 &lt;p&gt;Today I share with you the 6 key points that make our Tech Team thrive at Toucan.&lt;/p&gt; 
 &lt;h2&gt;1. Healthy and Participatory Engineering Culture&lt;/h2&gt; 
 &lt;p&gt;The Tech Team at Toucan is organized in squads. And in each squad, we foster a collegial atmosphere that allows for constructive exchanges and informed decision making.&lt;/p&gt; 
 &lt;p&gt;We take feedback &amp;amp; contributions from squad members before making a decision. We listen to suggestions on team organization, task distribution, and technical choices. We encourage feedback as much as possible. This allows us to tackle issues before they become real organizational or technical problems. Everyone is the guardian of his or her environment.&lt;/p&gt; 
 &lt;p&gt;In the end, when a decision must be made, it may not always be in everyone’s favor, but it will be enlightened.&lt;/p&gt; 
 &lt;blockquote&gt; 
  &lt;p&gt;According to Nino, “we’re very mature in our ability to question our code. We have frequent feedback with the whole team and we list the keep/drop/try. That allows us to define clear action points. Therefore, there are very few painful subjects that we let grow.”&lt;/p&gt; 
 &lt;/blockquote&gt; 
 &lt;h2&gt;2. A Qualitative approach to produce Serenely&lt;/h2&gt; 
 &lt;p&gt;Creating a healthy environment involves several aspects. One of them is in our opinion the ability to produce something qualitative within a reasonable time frame leaving room for reflection &amp;amp; iterations.&lt;/p&gt; 
 &lt;p&gt;This allows us to do things really well, not to leave big problems behind, and to produce code that we can be proud of.&lt;/p&gt; 
 &lt;blockquote&gt; 
  &lt;p&gt;Molka says it very well: “We bet a lot on the quality of our code, so we don’t hesitate to take time to refactor when needed and make the code clearer and easier to maintain.”&lt;/p&gt; 
 &lt;/blockquote&gt; 
 &lt;h2&gt;3. Culture of Learning and Growing Together&lt;/h2&gt; 
 &lt;p&gt;What often comes up when Tokars are asked why they enjoy working at Toucan is the opportunity to learn and grow professionally.&lt;/p&gt; 
 &lt;p&gt;At Toucan, it’s all about helping each other and the culture of feedback… #EachOneTeachOne&lt;/p&gt; 
 &lt;p&gt;A high level of collaboration can be observed in the Tech teams. This translates into the possibility of soliciting each other when you are stuck. Team members always ensure they have time in their agenda to provide code review, give constructive feedback, do peer-programming, share knowledge on a topic via Tuesday Tech Talk, etc.&lt;/p&gt; 
 &lt;p&gt;When a team member reaches the end of their adventure in a squad, or on a topic, we are able to switch them to other challenges, and integrate them into other teams in view to continue their development with us.&lt;/p&gt; 
 &lt;h2&gt;4. Trust at the heart of our Productivity&lt;/h2&gt; 
 &lt;p&gt;At Toucan, we believe that trusting is essential. Giving everyone the space to organize themselves and create their own balance between professional / personal life is what allows for a good level of productivity and well-being at work.&lt;/p&gt; 
 &lt;p&gt;We all have OKRs to reach, a team to support. We also all have a life outside of work. Having a balance between professional and personal life is important. But above all, we don’t all have the cursor in the same place and don’t all produce at the same pace.&lt;/p&gt; 
 &lt;p&gt;And that’s why we have allowed a lot of flexibility in the organization of work time and environment. Here are a few examples:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt; &lt;p&gt;Flexibility on working hours: Everyone organizes his day as they consider necessary and according to their professional &amp;amp; personal imperatives.&lt;/p&gt; &lt;/li&gt; 
  &lt;li&gt; &lt;p&gt;Occasional remote work at everyone’s discretion: We do not monitor or regulate remote working. Everyone is free to work from home when they need to. #InTokarsWeTrust: Trust is at the center of our practices.&lt;/p&gt; &lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;h2&gt;5. A software product rich in possibilities&lt;/h2&gt; 
 &lt;p&gt;We are developing a Data Visualization software product, whose mission is to to turn data into clear insights for everyone through pedagogy&lt;/p&gt; 
 &lt;p&gt;We are working in an industry that offers an almost infinite number of subjects, with a high level of complexity and therefore with infinite possibilities. What’s more, we’re taking the subject of Data Visualization from a new angle. We are prototyping new ways to visualize Data. So our daily work consists of trying, iterating, and finally industrializing. It is a complete and complex production cycle, and it is very rewarding to see the product evolve over time.&lt;/p&gt; 
 &lt;h2&gt;6. Last but not least: a close-knit team&lt;/h2&gt; 
 &lt;p&gt;What comes up very often is the high level of collaboration, and the fact that the team is very close-knit. Our teams are made up of very heterogeneous profiles, with all kinds of different backgrounds and very scattered degrees of seniority. However, when we ask them what they like about Toucan, and why they stay with us, this answer always comes back: My team.&lt;/p&gt; 
 &lt;p&gt;We have managed to create a strong bond within the entire Tech Team through mutual help and moments of sharing (game nights, hackathons, Tuesday talk) without falling into the bad habits of the start-up world -&amp;gt; everyone is free to participate or not, there is no pressure or obligation. Because once again, we all have different needs and desires.&lt;/p&gt; 
 &lt;p&gt;Here are the reasons why our Tech Team is thriving and our environment is healthy. If you feel related to what you’ve just read, know that we are recruiting !&lt;/p&gt; 
 &lt;p&gt;Visit our career page now: &lt;a href="https://toucantoco.com/fr/team.html#jobs"&gt;https://toucantoco.com/fr/team.html#jobs&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/6-reasons-to-join-our-tech-team" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/office-2.webp" alt="6 Reasons to join our Tech Team | Toucan Toco" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;div class="post"&gt; 
 &lt;a class="post__back-to-blog" href="https://www.toucantoco.com/en/tech-blog.html"&gt; &lt;/a&gt; 
 &lt;br&gt; 
 &lt;p&gt;I recently asked my team “Why do you like working at Toucan”. And I was amazed at how closely aligned their opinions were on the subject.&lt;/p&gt; 
 &lt;p&gt;Today I share with you the 6 key points that make our Tech Team thrive at Toucan.&lt;/p&gt; 
 &lt;h2&gt;1. Healthy and Participatory Engineering Culture&lt;/h2&gt; 
 &lt;p&gt;The Tech Team at Toucan is organized in squads. And in each squad, we foster a collegial atmosphere that allows for constructive exchanges and informed decision making.&lt;/p&gt; 
 &lt;p&gt;We take feedback &amp;amp; contributions from squad members before making a decision. We listen to suggestions on team organization, task distribution, and technical choices. We encourage feedback as much as possible. This allows us to tackle issues before they become real organizational or technical problems. Everyone is the guardian of his or her environment.&lt;/p&gt; 
 &lt;p&gt;In the end, when a decision must be made, it may not always be in everyone’s favor, but it will be enlightened.&lt;/p&gt; 
 &lt;blockquote&gt; 
  &lt;p&gt;According to Nino, “we’re very mature in our ability to question our code. We have frequent feedback with the whole team and we list the keep/drop/try. That allows us to define clear action points. Therefore, there are very few painful subjects that we let grow.”&lt;/p&gt; 
 &lt;/blockquote&gt; 
 &lt;h2&gt;2. A Qualitative approach to produce Serenely&lt;/h2&gt; 
 &lt;p&gt;Creating a healthy environment involves several aspects. One of them is in our opinion the ability to produce something qualitative within a reasonable time frame leaving room for reflection &amp;amp; iterations.&lt;/p&gt; 
 &lt;p&gt;This allows us to do things really well, not to leave big problems behind, and to produce code that we can be proud of.&lt;/p&gt; 
 &lt;blockquote&gt; 
  &lt;p&gt;Molka says it very well: “We bet a lot on the quality of our code, so we don’t hesitate to take time to refactor when needed and make the code clearer and easier to maintain.”&lt;/p&gt; 
 &lt;/blockquote&gt; 
 &lt;h2&gt;3. Culture of Learning and Growing Together&lt;/h2&gt; 
 &lt;p&gt;What often comes up when Tokars are asked why they enjoy working at Toucan is the opportunity to learn and grow professionally.&lt;/p&gt; 
 &lt;p&gt;At Toucan, it’s all about helping each other and the culture of feedback… #EachOneTeachOne&lt;/p&gt; 
 &lt;p&gt;A high level of collaboration can be observed in the Tech teams. This translates into the possibility of soliciting each other when you are stuck. Team members always ensure they have time in their agenda to provide code review, give constructive feedback, do peer-programming, share knowledge on a topic via Tuesday Tech Talk, etc.&lt;/p&gt; 
 &lt;p&gt;When a team member reaches the end of their adventure in a squad, or on a topic, we are able to switch them to other challenges, and integrate them into other teams in view to continue their development with us.&lt;/p&gt; 
 &lt;h2&gt;4. Trust at the heart of our Productivity&lt;/h2&gt; 
 &lt;p&gt;At Toucan, we believe that trusting is essential. Giving everyone the space to organize themselves and create their own balance between professional / personal life is what allows for a good level of productivity and well-being at work.&lt;/p&gt; 
 &lt;p&gt;We all have OKRs to reach, a team to support. We also all have a life outside of work. Having a balance between professional and personal life is important. But above all, we don’t all have the cursor in the same place and don’t all produce at the same pace.&lt;/p&gt; 
 &lt;p&gt;And that’s why we have allowed a lot of flexibility in the organization of work time and environment. Here are a few examples:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt; &lt;p&gt;Flexibility on working hours: Everyone organizes his day as they consider necessary and according to their professional &amp;amp; personal imperatives.&lt;/p&gt; &lt;/li&gt; 
  &lt;li&gt; &lt;p&gt;Occasional remote work at everyone’s discretion: We do not monitor or regulate remote working. Everyone is free to work from home when they need to. #InTokarsWeTrust: Trust is at the center of our practices.&lt;/p&gt; &lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;h2&gt;5. A software product rich in possibilities&lt;/h2&gt; 
 &lt;p&gt;We are developing a Data Visualization software product, whose mission is to to turn data into clear insights for everyone through pedagogy&lt;/p&gt; 
 &lt;p&gt;We are working in an industry that offers an almost infinite number of subjects, with a high level of complexity and therefore with infinite possibilities. What’s more, we’re taking the subject of Data Visualization from a new angle. We are prototyping new ways to visualize Data. So our daily work consists of trying, iterating, and finally industrializing. It is a complete and complex production cycle, and it is very rewarding to see the product evolve over time.&lt;/p&gt; 
 &lt;h2&gt;6. Last but not least: a close-knit team&lt;/h2&gt; 
 &lt;p&gt;What comes up very often is the high level of collaboration, and the fact that the team is very close-knit. Our teams are made up of very heterogeneous profiles, with all kinds of different backgrounds and very scattered degrees of seniority. However, when we ask them what they like about Toucan, and why they stay with us, this answer always comes back: My team.&lt;/p&gt; 
 &lt;p&gt;We have managed to create a strong bond within the entire Tech Team through mutual help and moments of sharing (game nights, hackathons, Tuesday talk) without falling into the bad habits of the start-up world -&amp;gt; everyone is free to participate or not, there is no pressure or obligation. Because once again, we all have different needs and desires.&lt;/p&gt; 
 &lt;p&gt;Here are the reasons why our Tech Team is thriving and our environment is healthy. If you feel related to what you’ve just read, know that we are recruiting !&lt;/p&gt; 
 &lt;p&gt;Visit our career page now: &lt;a href="https://toucantoco.com/fr/team.html#jobs"&gt;https://toucantoco.com/fr/team.html#jobs&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2F6-reasons-to-join-our-tech-team&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Thu, 28 Jan 2021 05:00:00 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/6-reasons-to-join-our-tech-team</guid>
      <dc:date>2021-01-28T05:00:00Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Mocking a getter in Vuex + Jest</title>
      <link>https://www.toucantoco.com/en/tech-blog/mocking-a-getter</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/mocking-a-getter" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/indiana-jones.webp" alt="Indiana Jones replacing an ancient relic by a bag of dirt" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Let’s say you want to unit test a component which behavior depends on a Vuex getter.&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/mocking-a-getter" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/indiana-jones.webp" alt="Indiana Jones replacing an ancient relic by a bag of dirt" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Let’s say you want to unit test a component which behavior depends on a Vuex getter.&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Fmocking-a-getter&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Thu, 15 Oct 2020 04:00:00 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/mocking-a-getter</guid>
      <dc:date>2020-10-15T04:00:00Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Releases that adapt to your desired speed | Toucan Toco</title>
      <link>https://www.toucantoco.com/en/tech-blog/weekly-monthly-releases</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/weekly-monthly-releases" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/bicycle-train-1.webp" alt="Bicycle courier transferring urgent mail onto a high-speed train" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Overtime, we’ve gathered a lot of different feedbacks from different types of users about our release process. These feedbacks are very precious to us. They are guiding our every-day actions and sometimes inititate bigger changes. This article tells the story of one of the latter.&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/weekly-monthly-releases" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/bicycle-train-1.webp" alt="Bicycle courier transferring urgent mail onto a high-speed train" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Overtime, we’ve gathered a lot of different feedbacks from different types of users about our release process. These feedbacks are very precious to us. They are guiding our every-day actions and sometimes inititate bigger changes. This article tells the story of one of the latter.&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Fweekly-monthly-releases&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Sat, 06 Jul 2019 04:00:00 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/weekly-monthly-releases</guid>
      <dc:date>2019-07-06T04:00:00Z</dc:date>
      <dc:creator>David Nowinsky</dc:creator>
    </item>
    <item>
      <title>How to automate monitoring of 200 customer stacks in 1 deployment</title>
      <link>https://www.toucantoco.com/en/tech-blog/ansible_monitoring</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/ansible_monitoring" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Company%20-%20Tech%20Blog/buzz_lightning-monitoring.webp" alt="Buzz Lightyear talking about Monitoring to Woody" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;div class="post"&gt; 
 &lt;p&gt;Very quickly to deploy a new stack, we made a suite of playbooks &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;. They are in charge of provisioning the target machine with the stack and all its dependencies, adjusting the environment (such as fail2ban rules, etc…), but nothing was managed for our supervision.&lt;/p&gt; 
 &lt;p&gt;Rather than managing the monitoring of the different bricks of each instance with an agent-based tool like &lt;a href="https://www.nagios.org/"&gt;Nagios&lt;/a&gt; (to be deployed, configured and updated on each server), the first version of our monitoring was done using the free trial proposed by &lt;a href="https://www.statuscake.com/"&gt;StatusCake&lt;/a&gt;. This service allows you to ping a given URL at regular intervals, and to send alerts via &lt;a href="https://slack.com/"&gt;Slack&lt;/a&gt; or email.&lt;/p&gt; 
 &lt;h2&gt;The problem: doing everything manually&lt;/h2&gt; 
 &lt;p&gt;As this part was not automated, the creation of the tests &lt;a href="https://www.statuscake.com/"&gt;StatusCake&lt;/a&gt; was done manually by going to the web interface as described in our documentation for initializing a new stack. Creating checks on the[StatusCake] interface (https://www.statuscake.com/) is relatively simple but remains tedious with the multiplication of projects.&lt;/p&gt; 
 &lt;p&gt;Each time you have to connect to the interface, find the credentials, be sure that you create the test with the right options like the other tests, click, click, click and click again… As a result, no one wants to do it and we are exposed to mistakes.&lt;/p&gt; 
 &lt;p&gt;The penalty is the same when you have to update the tests (for example, to add conditions or parameters). Scaling might become compromised quickly.&lt;/p&gt; 
 &lt;h2&gt;The solution with Ansible!&lt;/h2&gt; 
 &lt;p&gt;With the multiplication of customers and projects, the need to automate the creation and updating of monitoring has therefore quickly become apparent. Knowing that the deployment and update of our stacks are already automated by our scripts &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;… Why not delegate the creation of these checks directly to it?&lt;/p&gt; 
 &lt;p&gt;In our case, we would like to have different types of checks concerning the health of our services:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;a check to make sure that our service is up&lt;/li&gt; 
  &lt;li&gt;a check to make sure that this service can communicate with the different techonologies on which it depends (MongoDB, Redis, etc.)&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;These two points match the distinction between &lt;em&gt;liveness&lt;/em&gt; and &lt;em&gt;readiness&lt;/em&gt;, well described in an Octo article: [Liveness and readiness probes: Put intelligence into your clusters] (https://blog.octo.com/liveness-et-readiness-probes-mettez-de-lintelligence-dans-vos-clusters/):&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;&lt;em&gt;liveness&lt;/em&gt;: if the check does not have an answer then an alert is raised, the service is considered as KO&lt;/li&gt; 
  &lt;li&gt;&lt;em&gt;readiness&lt;/em&gt;: according check’s anwser, we know if our service is “ready to be used”: just because we have an answer does not mean that the service is OK&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;The implementation of these checks requires the provision of 2 dedicated routes, on our service:&lt;/p&gt; 
 &lt;div class="language-python highlighter-rouge"&gt; 
  &lt;div class="highlight"&gt; 
   &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/liveness'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;liveness&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/readiness'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;readiness&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;redis_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mongo_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pymongo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionFailure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"KO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;ul&gt; 
  &lt;li&gt;&lt;em&gt;liveness&lt;/em&gt;: if the check on &lt;code class="language-plaintext highlighter-rouge"&gt;/liveness&lt;/code&gt; does not answer then our service is considered KO no matter what happens&lt;/li&gt; 
  &lt;li&gt;&lt;em&gt;readiness&lt;/em&gt;: if the check on &lt;code class="language-plaintext highlighter-rouge"&gt;/readiness&lt;/code&gt; returns 200 then the stack is considered OK because the connection to third-party services Redis and Mongo are OK&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;As for scripts &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;, we have created a custom module in python &lt;a href="https://github.com/labynocle/ansible-statuscake"&gt;ansible-statuscake&lt;/a&gt; (forked from&lt;a href="https://github.com/p404/ansible-statuscake"&gt;p404/ansible-statuscake&lt;/a&gt; which is no longer maintained). This module is used in this way:&lt;/p&gt; 
 &lt;div class="language-yaml highlighter-rouge"&gt; 
  &lt;div class="highlight"&gt; 
   &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create StatusCake test&lt;/span&gt;
  &lt;span class="na"&gt;local_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;status_cake_test&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-user"&lt;/span&gt;
    &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;       &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-api-key"&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check"&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;           &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://myservice.example.com"&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;         &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;present"&lt;/span&gt;
    &lt;span class="na"&gt;test_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP"&lt;/span&gt;
    &lt;span class="na"&gt;check_rate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="m"&gt;60&lt;/span&gt;  &lt;span class="c1"&gt;# on check toutes les minutes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;p&gt;In order for &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; to find this custom module, you must place the python script &lt;code class="language-plaintext highlighter-rouge"&gt;status_cake_test.py&lt;/code&gt; in the &lt;code class="language-plaintext highlighter-rouge"&gt;library&lt;/code&gt; folder at the root of the playbook.&lt;/p&gt; 
 &lt;p&gt;*Technical note: here, since we use a `local_action’, the execution takes place on the machine that starts the deployment, not on the target machine. In such a context, we can therefore benefit from the python interpreter and pip packages of our choice, without depending on the target machine. This was useful for us to create another annihilable module in python 3 / asyncio, which allowed us to rewrite some tasks using a competing model and thus save us deployment speed.&lt;/p&gt; 
 &lt;h2&gt;Some stats to finish….&lt;/h2&gt; 
 &lt;p&gt;Today, thanks to this approach:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;we have created and automatically maintain about 1000 tests for our 200 stacks&lt;/li&gt; 
  &lt;li&gt;test configuration is done via [Ansible] variables (https://www.ansible.com/) which are automatically committed, reviewed and applied to each stack deployment&lt;/li&gt; 
  &lt;li&gt;when a project is decomposed, all associated tests are automatically deleted: so our monitoring is always the same as our production&lt;/li&gt; 
  &lt;li&gt;StatusCake allows us to raise alerts on HTTP codes, patterns found in the response, response times… and allows us to do several different types of checks (performance, healthchecks,…)&lt;/li&gt; 
  &lt;li&gt;allows the calculation of &lt;a href="https://fr.wikipedia.org/wiki/Service-level_agreement"&gt;SLA&lt;/a&gt; at the scale of each instance by an external source which is in the same conditions as our customers, we finally have only to extract the data collected during the tests&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/div&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/ansible_monitoring" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Company%20-%20Tech%20Blog/buzz_lightning-monitoring.webp" alt="Buzz Lightyear talking about Monitoring to Woody" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;div class="post"&gt; 
 &lt;p&gt;Very quickly to deploy a new stack, we made a suite of playbooks &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;. They are in charge of provisioning the target machine with the stack and all its dependencies, adjusting the environment (such as fail2ban rules, etc…), but nothing was managed for our supervision.&lt;/p&gt; 
 &lt;p&gt;Rather than managing the monitoring of the different bricks of each instance with an agent-based tool like &lt;a href="https://www.nagios.org/"&gt;Nagios&lt;/a&gt; (to be deployed, configured and updated on each server), the first version of our monitoring was done using the free trial proposed by &lt;a href="https://www.statuscake.com/"&gt;StatusCake&lt;/a&gt;. This service allows you to ping a given URL at regular intervals, and to send alerts via &lt;a href="https://slack.com/"&gt;Slack&lt;/a&gt; or email.&lt;/p&gt; 
 &lt;h2&gt;The problem: doing everything manually&lt;/h2&gt; 
 &lt;p&gt;As this part was not automated, the creation of the tests &lt;a href="https://www.statuscake.com/"&gt;StatusCake&lt;/a&gt; was done manually by going to the web interface as described in our documentation for initializing a new stack. Creating checks on the[StatusCake] interface (https://www.statuscake.com/) is relatively simple but remains tedious with the multiplication of projects.&lt;/p&gt; 
 &lt;p&gt;Each time you have to connect to the interface, find the credentials, be sure that you create the test with the right options like the other tests, click, click, click and click again… As a result, no one wants to do it and we are exposed to mistakes.&lt;/p&gt; 
 &lt;p&gt;The penalty is the same when you have to update the tests (for example, to add conditions or parameters). Scaling might become compromised quickly.&lt;/p&gt; 
 &lt;h2&gt;The solution with Ansible!&lt;/h2&gt; 
 &lt;p&gt;With the multiplication of customers and projects, the need to automate the creation and updating of monitoring has therefore quickly become apparent. Knowing that the deployment and update of our stacks are already automated by our scripts &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;… Why not delegate the creation of these checks directly to it?&lt;/p&gt; 
 &lt;p&gt;In our case, we would like to have different types of checks concerning the health of our services:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;a check to make sure that our service is up&lt;/li&gt; 
  &lt;li&gt;a check to make sure that this service can communicate with the different techonologies on which it depends (MongoDB, Redis, etc.)&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;These two points match the distinction between &lt;em&gt;liveness&lt;/em&gt; and &lt;em&gt;readiness&lt;/em&gt;, well described in an Octo article: [Liveness and readiness probes: Put intelligence into your clusters] (https://blog.octo.com/liveness-et-readiness-probes-mettez-de-lintelligence-dans-vos-clusters/):&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;&lt;em&gt;liveness&lt;/em&gt;: if the check does not have an answer then an alert is raised, the service is considered as KO&lt;/li&gt; 
  &lt;li&gt;&lt;em&gt;readiness&lt;/em&gt;: according check’s anwser, we know if our service is “ready to be used”: just because we have an answer does not mean that the service is OK&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;The implementation of these checks requires the provision of 2 dedicated routes, on our service:&lt;/p&gt; 
 &lt;div class="language-python highlighter-rouge"&gt; 
  &lt;div class="highlight"&gt; 
   &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/liveness'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;liveness&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/readiness'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;readiness&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;redis_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mongo_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pymongo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionFailure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"KO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;ul&gt; 
  &lt;li&gt;&lt;em&gt;liveness&lt;/em&gt;: if the check on &lt;code class="language-plaintext highlighter-rouge"&gt;/liveness&lt;/code&gt; does not answer then our service is considered KO no matter what happens&lt;/li&gt; 
  &lt;li&gt;&lt;em&gt;readiness&lt;/em&gt;: if the check on &lt;code class="language-plaintext highlighter-rouge"&gt;/readiness&lt;/code&gt; returns 200 then the stack is considered OK because the connection to third-party services Redis and Mongo are OK&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;As for scripts &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt;, we have created a custom module in python &lt;a href="https://github.com/labynocle/ansible-statuscake"&gt;ansible-statuscake&lt;/a&gt; (forked from&lt;a href="https://github.com/p404/ansible-statuscake"&gt;p404/ansible-statuscake&lt;/a&gt; which is no longer maintained). This module is used in this way:&lt;/p&gt; 
 &lt;div class="language-yaml highlighter-rouge"&gt; 
  &lt;div class="highlight"&gt; 
   &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create StatusCake test&lt;/span&gt;
  &lt;span class="na"&gt;local_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;status_cake_test&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-user"&lt;/span&gt;
    &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;       &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-api-key"&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check"&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;           &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://myservice.example.com"&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;         &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;present"&lt;/span&gt;
    &lt;span class="na"&gt;test_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP"&lt;/span&gt;
    &lt;span class="na"&gt;check_rate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="m"&gt;60&lt;/span&gt;  &lt;span class="c1"&gt;# on check toutes les minutes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;p&gt;In order for &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; to find this custom module, you must place the python script &lt;code class="language-plaintext highlighter-rouge"&gt;status_cake_test.py&lt;/code&gt; in the &lt;code class="language-plaintext highlighter-rouge"&gt;library&lt;/code&gt; folder at the root of the playbook.&lt;/p&gt; 
 &lt;p&gt;*Technical note: here, since we use a `local_action’, the execution takes place on the machine that starts the deployment, not on the target machine. In such a context, we can therefore benefit from the python interpreter and pip packages of our choice, without depending on the target machine. This was useful for us to create another annihilable module in python 3 / asyncio, which allowed us to rewrite some tasks using a competing model and thus save us deployment speed.&lt;/p&gt; 
 &lt;h2&gt;Some stats to finish….&lt;/h2&gt; 
 &lt;p&gt;Today, thanks to this approach:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;we have created and automatically maintain about 1000 tests for our 200 stacks&lt;/li&gt; 
  &lt;li&gt;test configuration is done via [Ansible] variables (https://www.ansible.com/) which are automatically committed, reviewed and applied to each stack deployment&lt;/li&gt; 
  &lt;li&gt;when a project is decomposed, all associated tests are automatically deleted: so our monitoring is always the same as our production&lt;/li&gt; 
  &lt;li&gt;StatusCake allows us to raise alerts on HTTP codes, patterns found in the response, response times… and allows us to do several different types of checks (performance, healthchecks,…)&lt;/li&gt; 
  &lt;li&gt;allows the calculation of &lt;a href="https://fr.wikipedia.org/wiki/Service-level_agreement"&gt;SLA&lt;/a&gt; at the scale of each instance by an external source which is in the same conditions as our customers, we finally have only to extract the data collected during the tests&lt;/li&gt; 
 &lt;/ul&gt; 
&lt;/div&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Fansible_monitoring&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Mon, 25 Mar 2019 04:00:00 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/ansible_monitoring</guid>
      <dc:date>2019-03-25T04:00:00Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Test any code, even the code you are not proud of | Toucan Toco</title>
      <link>https://www.toucantoco.com/en/tech-blog/patterns-unit-testing</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/patterns-unit-testing" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/we-dont-test-that-2.webp" alt="Test any code, even the code you are not proud of | Toucan Toco" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;A pragmatic approach to unit testing in legacy code (code that people think isn’t testable and that nobody wants to touch anymore). Using simple mocks and design patterns, in javascript.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Once upon a time…&lt;/h2&gt; 
&lt;p&gt;Have you ever heard something like:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“It’s ok, we don’t test that code.”&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“Are you sure you want to touch that code? You might break something.”&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Sounds familiar no? Usually, it even refers to the same code.&lt;/p&gt; 
&lt;p&gt;Testing in “good” code is &lt;a href="https://vue-test-utils.vuejs.org/guides/#test-rendered-html-output-of-the-component"&gt;really easy&lt;/a&gt;. Just follow the documentation! By “good” code, I mean:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Code that everyone in your team understands (readability)&lt;/li&gt; 
 &lt;li&gt;Code that everyone in your team loves to contribute to, and they do it very fast (maintainability)&lt;/li&gt; 
 &lt;li&gt;Code that everyone in your team &lt;em&gt;agrees&lt;/em&gt; on (best practices, conventions)&lt;/li&gt; 
 &lt;li&gt;If you use a library / framework: 
  &lt;ul&gt; 
   &lt;li&gt;the library / framework is recent (or at least it is still maintained)&lt;/li&gt; 
   &lt;li&gt;it is quite common (today: VueJS, React, Angular…), or at least uses common concepts so that you can on-board new devs on it easily&lt;/li&gt; 
   &lt;li&gt;the code follows the common patterns and practices of this library / framework&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Luckily for us we have all these libraries/frameworks that (supposedly) make our life very easy. But let’s remember again, have you ever heard something like:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“Use framework/tool XXXX you will see, it is so awesome, it’s going to work perfectly!! You’re going to love it!&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;And then you’re like&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Ok XXXX seems great! I’m going to start using it all over the place, wohooo!&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Some weeks later&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Oh I have to do this feature very fast, let’s just do this small hack, by using this dark feature of the framework. It’s ok, temporarily. (…)&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;We’re so late! We will write tests later.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Over the weeks, people have extracted this code into an utility and is used in 10% of your 100 000 lines of code app.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Let’s upgrade XXXX! (…) Oh my god, what have we done? This is going to take months!&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;So I bet that all your code is not “good” code, and that you have to deal with legacy code (as most developers have to). If you don’t think you have legacy code, I am pretty sure you are going to change your mind in a couple of months.&lt;/p&gt; 
&lt;p&gt;That is because most code have an expiration date, more or less in the future. No one can escape that. We are humans, we are limited, we have to take difficult decisions. We have to think about the long term in a very fast changing environment. And sometimes, we make small mistakes. Overtime, these mistakes accumulate to make a mess. But I think it is OK. We have to accept that &lt;em&gt;the code we write today is the legacy code of tomorrow&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;But we can still &lt;em&gt;improve&lt;/em&gt; this code. Even if your code has expired for so long that’s it’s become a rotten spaghetti monster. The one that smells so bad that you are really afraid of it, you avoid touching any of it, and you dream of trashing it once and for all.&lt;/p&gt; 
&lt;p&gt;So let’s start to “Make &lt;em&gt;your code&lt;/em&gt; great again”!&lt;/p&gt; 
&lt;p&gt;How do you do that? There are already well known community-approved solutions:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tests (and related methodologies such as TDD)&lt;/li&gt; 
 &lt;li&gt;Thorough code reviews&lt;/li&gt; 
 &lt;li&gt;Pair programing, mob programming or other kind of group work&lt;/li&gt; 
 &lt;li&gt;Domain Driven Design&lt;/li&gt; 
 &lt;li&gt;“Slack time” to refactor&lt;/li&gt; 
 &lt;li&gt;Zero bug policy&lt;/li&gt; 
 &lt;li&gt;…&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;This article focuses on &lt;em&gt;unit tests&lt;/em&gt;. I think tests are one of the most difficult thing to do with legacy code. But it’s one of the most important things to do. Sadly, it’s also one of the things that is often put aside, especially in front end development.&lt;/p&gt; 
&lt;p&gt;Tests allows you to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;prove&lt;/em&gt; that your code works as expected for your end user&lt;/li&gt; 
 &lt;li&gt;explain your code to the next developer that will have to maintain it&lt;/li&gt; 
 &lt;li&gt;have better technical designs by forcing you to isolate logical units (so you can test them)&lt;/li&gt; 
 &lt;li&gt;write exhaustive functional specifications of your component (made explicit by tests titles, like “it should do this”)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;I will talk more about why we should test in another article.&lt;/p&gt; 
&lt;p&gt;We will see that there are a lot of choices that we will have to do while writing tests. But one thing should help us make those choices: we should &lt;em&gt;be as pragmatic as possible&lt;/em&gt; in our test strategy.&lt;/p&gt; 
&lt;p&gt;We want to spend only the time we can afford to on those tests: not a few seconds, nor a few months. Just the time needed to write tests in our new code so that the following can be achieved :&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;the tests prove that what’s important for the end user will work&lt;/li&gt; 
 &lt;li&gt;the tests explain the logic behind your code for the next developer that will have to change it&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;We also want to test &lt;em&gt;only&lt;/em&gt; your new code. We don’t want to take months to refactor the entire existing codebase and write unit tests for all of it. We’re taking a pragmatic incremental approach: &lt;em&gt;every new logic should be tested&lt;/em&gt;. We don’t want to test libraries or tools either: for exemple, we trust that the browser will display a &lt;code class="language-plaintext highlighter-rouge"&gt;&amp;lt;div&amp;gt;&lt;/code&gt; correctly.&lt;/p&gt; 
&lt;p&gt;Of course you can spend more time &lt;em&gt;if you can afford it&lt;/em&gt;. You will then refactor more, test more existing code. That will lead to: better designs, exhaustive functional specifications… But be careful; you also want to deliver functionality to you end users. Think about what’s best for them and for your team.&lt;/p&gt; 
&lt;p&gt;So let’s start to write tests! Every section below contains a pragmatic approach to test in legacy code; at the end of each section, a recap sums up the pros and cons of the approach.&lt;/p&gt; 
&lt;h2&gt;Use the framework!&lt;/h2&gt; 
&lt;p&gt;If the code you want to contribute to uses a framework that supports testing, just follow the documentation of this framework! But I think that if you are reading this, you have to deal with a tricky codebase that have old frameworks or old code that is hardly testable.&lt;/p&gt; 
&lt;p&gt;If you want to create a component or add much functionality to an existing component, you can just refactor directly into a “new” framework. And it’s feasible, using the &lt;a href="https://en.wikipedia.org/wiki/Adapter_pattern"&gt;Adapter&lt;/a&gt; design pattern (also called wrapper).&lt;/p&gt; 
&lt;p&gt;As an example, I recently updated the design of the login page in the Toucan Toco front end. Because the login page is one of the first thing you have to do when you make a front end, the code was an old AngularJS mess. I re-wrote the component with TDD in less than one week, in VueJS, using an Adapter.&lt;/p&gt; 
&lt;p&gt;The adapter between vueJS and AngularJS looks like this:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// The vue component&lt;/span&gt;

&lt;span class="nx"&gt;angular&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loginNg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;restrict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;E&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div class="login__vue-placeholder"&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginWrapperVm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.login__vue-placeholder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// 1. Insertion in the DOM&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login-wrapper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;authenticationManager&lt;/span&gt; &lt;span class="c1"&gt;// 3. Adaptation of an old angular service&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$destroy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;loginWrapperVm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$destroy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 2. Adaptation of 'destroy' lifecycle.&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;We will talk about our approach to incremental refactoring from AngularJS to VueJS in another article (coming up soon).&lt;/p&gt; 
&lt;p&gt;This adapter has the role to adapt the AngularJS API to the VueJS API. We can see three interesting adaptations:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The insertion in the DOM&lt;/li&gt; 
 &lt;li&gt;The destroy lifecycle&lt;/li&gt; 
 &lt;li&gt;The authenticationManager service&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The authenticationManager service is particularly interesting. I wanted to change the Login page was designed, not the way that all the login and authentication works.&lt;/p&gt; 
&lt;p&gt;This AngularJS service deals with many aspects of authentication in the app. My first thought was to refactor it as well. But it is a very complex class (400 lines of code) with a lot of state hidden inside. It is also used widely in different parts of the legacy code: I would have had to refactor that as well. So refactoring would have been very difficult, and instead of a week, it would have taken a month.&lt;/p&gt; 
&lt;p&gt;But injection comes to our rescue! When you want to partially refactor a component without changing all the code that depends on this component, you can just inject the “old” objects that have to be called from your refactored code. For our Login VueJS component, it goes like this:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="na"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authenticationManager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;// Some login component code ...&lt;/span&gt;

  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      
    &lt;span class="c1"&gt;// Some other methods ... &lt;/span&gt;
    
    &lt;span class="nx"&gt;performLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// HTTP call to the API&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLoginSuccessful&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Call to the legacy angular service dealing with authentication&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Many frameworks support injection, or similar mechanisms. Worst case scenario, you can pass your legacy APIs as object parameters of your component. You could even export a function that creates or returns the current instance of your legacy JS service (see the factory section).&lt;/p&gt; 
&lt;p&gt;Anyway, with that we have brand-new code using our “modern” framework and we’re happy. We know how to test it. But how do we test the Adapter? and the injection? Sadly, you can’t. You can only test that the injected object is called correctly in the new code:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;

  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockAuthenticationManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;onLoginSuccessful&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockAuthenticationManager&lt;/span&gt; 
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
        
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when the user inputs his username and his password, and then clicks login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... Set the username, password and clicks login ...&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should notify the authentication manager of the successful login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert that the legacy API have been called &lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockAuthenticationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLoginSuccessful&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USERNAME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOGIN_RESPONSE_DATA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;But it’s OK it’s just a few lines of code without any business rules (see my article on “What to test?”). It’s mostly boiler plate framework-code that we don’t really &lt;em&gt;care&lt;/em&gt; about. If it breaks, you will notice it pretty fast (the login page will not display). Also, it could be tested via multi-component tests or end-to-end tests.&lt;/p&gt; 
&lt;p&gt;Most of the times &lt;em&gt;you have to take pragmatic choices, and put things into perspective&lt;/em&gt;. The code is in better shape than before now (it follows conventions), and we have increased test coverage. But it is true that it is not &lt;em&gt;perfect&lt;/em&gt; and we introduced a new piece of code (the adapter) that is not tested, and does not follow the best practices of AngularJS nor VueJS. Also, it required a bit of work; that you might not have the time to do.&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;To sum up, the adapter:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;good to transform a significant piece of legacy code with an old framework into “new” code with a “modern” framework that you can test&lt;/li&gt; 
 &lt;li&gt;uses an adaptation code between the two frameworks&lt;/li&gt; 
 &lt;li&gt;uses injection for the pieces of code you don’t want to refactor (yet)&lt;/li&gt; 
 &lt;li&gt;requires a bit of work&lt;/li&gt; 
 &lt;li&gt;adds some code (the adapter) that we do not test&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;(Sort-of) Factory&lt;/h2&gt; 
&lt;p&gt;Let’s talk about the other cool trick that we have talked about in the previous section: the sort-of &lt;a href="https://en.wikipedia.org/wiki/Factory_method_pattern"&gt;Factory Pattern&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Factories are very useful to inject mock-objects at run-time for your tests. They also help you modularize your code. For example, let’s say we are in a chart component, and we want to add a new parameter to the chart legend.&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  
  &lt;span class="c1"&gt;// ... Some existing D3 JS code ...&lt;/span&gt;
  
  &lt;span class="c1"&gt;// This the new parameter that we want to test&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="c1"&gt;// Existing legacy code for the legend&lt;/span&gt;
  &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.my-chart__legend-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Not easily testable code (for some reason)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;makeExtraInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// More complex untestable code that depend on displayExtraInformation...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Let’s also say the code in the &lt;code class="language-plaintext highlighter-rouge"&gt;text&lt;/code&gt; callback is not easily testable (for some reason). So it is hard to test independently when &lt;code class="language-plaintext highlighter-rouge"&gt;displayExtraInformation&lt;/code&gt; is true or not. You could export a getter to this boolean if you make it global, but then it won’t be a &lt;code class="language-plaintext highlighter-rouge"&gt;const&lt;/code&gt; anymore and it would degrade the design by putting the variable as a ‘state’ variable. Also, it’s a lot of modifications that does not necessarily clarify the code.&lt;/p&gt; 
&lt;p&gt;Let’s see if we can separate the legend in a different module (which make sense, it is a different component, functionally):&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charts/legend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  
  &lt;span class="c1"&gt;// ... Some existing D3 JS code ...&lt;/span&gt;
  
  &lt;span class="c1"&gt;// This is the new code that we want to test&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  
  &lt;span class="c1"&gt;// New function !&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Other parameters..&lt;/span&gt;
    &lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  
  &lt;span class="c1"&gt;// Wiring to the legacy&lt;/span&gt;
  &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.my-chart__legend-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myChartLegend&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ... other D3 JS code ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;and in ‘charts/legend/index.js’:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;selection&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Not easily testable code (for some reason)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;makeExtraInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// More complex untestable code that depend on displayExtraInformation...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Now we can stub the &lt;code class="language-plaintext highlighter-rouge"&gt;createChartLegend&lt;/code&gt; and assert the call in our tests! Using the import syntax we have the following:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sinon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charts/my-chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ChartLegendFactory&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charts/legend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;


&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    
  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartLegendFactoryStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ChartLegendFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartLegendFactoryStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should call the chartLegendFactory with displayExtraInformation as true when the chart is large enough&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drawMyChart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartLegendFactoryStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
    
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;If we didnt want to separate the chart legend in a seperate module, we would have done the following:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only used for testing&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setChartLegendFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;oldFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;oldFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Same as before&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// same as before&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;We would call &lt;code class="language-plaintext highlighter-rouge"&gt;setChartLegendFactory&lt;/code&gt; in &lt;code class="language-plaintext highlighter-rouge"&gt;beforeEach&lt;/code&gt;&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createChartStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLegendFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setChartLegendFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createChartStub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;And reinitialize it in &lt;code class="language-plaintext highlighter-rouge"&gt;afterEach&lt;/code&gt;, to avoid side-effects:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setChartLegendFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLegendFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Note that this adds some code (here, the &lt;code class="language-plaintext highlighter-rouge"&gt;setChartLegendFactory&lt;/code&gt; function) that is only used for test. It is quite common practice to open some functions or attributes only for testing purposes. Some may argue that it degrades the design of your code, but it is sometimes the most efficient way to be able to test something. I would use it as a &lt;em&gt;last resort&lt;/em&gt; when you don’t know how to do otherwise. But if you can inject your object using a clean technique that does not impact your production code, then you should do that instead.&lt;/p&gt; 
&lt;p&gt;You can also use the factory pattern to inject old legacy code into a new piece of code as we talked about in the Adapter section.&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;The (sort-of) factory pattern is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;good for testing small bits of “new” code calling the legacy code&lt;/li&gt; 
 &lt;li&gt;gives you the ability to inject objects or functions at run-time&lt;/li&gt; 
 &lt;li&gt;usually, this means mocking the legacy code&lt;/li&gt; 
 &lt;li&gt;also useful to inject legacy services into “new” code&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Functional programing&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Functional_programming"&gt;Functional programing&lt;/a&gt; is not a design pattern itself, but a paradigm we can follow to help us test our “new” code. We can see it as a programing style: make everything stateless functions. How can you achieve that? Simple:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Identify a block of code with business logic in it (a bunch of &lt;code class="language-plaintext highlighter-rouge"&gt;if&lt;/code&gt;, &lt;code class="language-plaintext highlighter-rouge"&gt;else&lt;/code&gt;s, and calculus). If the block is not clear, try to group the lines of code that seem independent.&lt;/li&gt; 
 &lt;li&gt;Identify the inputs and outputs of this block of code. Typically, input variables are variables used at the right of &lt;code class="language-plaintext highlighter-rouge"&gt;=&lt;/code&gt; and output are new variables declared at the left of &lt;code class="language-plaintext highlighter-rouge"&gt;=&lt;/code&gt;, and used later in the code.&lt;/li&gt; 
 &lt;li&gt;For the state-dependent variables, the same rule applies.&lt;/li&gt; 
 &lt;li&gt;Declare the outputs clearly at the end of your block of code.&lt;/li&gt; 
 &lt;li&gt;Create a separate function where parameters of this function are the inputs and the function returns an object containing all the outputs.&lt;/li&gt; 
 &lt;li&gt;Put the block of code into this new function; rename the variables if you have to.&lt;/li&gt; 
 &lt;li&gt;Call this function where the block of code was.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Got it? Let’s try that in practice. So our example is a D3 chart, and we want to change some part of the layout of this chart. Sadly, this chart is in legacy code, and not tested. We have an existing function &lt;code class="language-plaintext highlighter-rouge"&gt;scope.update&lt;/code&gt;; that does all the layout, and that is very long&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ... Some chart stuff ...&lt;/span&gt;
&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    
  &lt;span class="nx"&gt;drawVariation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;drawSparklines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  
  &lt;span class="c1"&gt;// ... some very long layout and draw logic&lt;/span&gt;
  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;So we add our new layout code, not refactored (yet):&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ... Some chart code...&lt;/span&gt;
&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;estimateValueWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variationSignWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklineWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drawVariation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;drawSparklines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some very long layout and draw logic un angular JS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Using the methodology I talked about before, we can clearly identify a block of code that &lt;em&gt;looks&lt;/em&gt; functional: the beginning of the code. It is pure math and assignments.&lt;/p&gt; 
&lt;p&gt;The inputs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;inputData&lt;/code&gt; array&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;chartOptions&lt;/code&gt; object&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;config&lt;/code&gt; object&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;width&lt;/code&gt; number&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;And the outputs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;the boolean &lt;code class="language-plaintext highlighter-rouge"&gt;shouldDisplaySparklines&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;the boolean &lt;code class="language-plaintext highlighter-rouge"&gt;shouldDisplayVariation&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;estimatedVariationWidth&lt;/code&gt; number&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;With that in mind, let’s create the prototype of our function:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;We named it &lt;code class="language-plaintext highlighter-rouge"&gt;layout&lt;/code&gt; after seeing the inputs and outputs: it has clearly something to do with &lt;code class="language-plaintext highlighter-rouge"&gt;layout&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;So now, copy paste our functional code block, renaming the variables a bit:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;estimateValueWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variationSignWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklineWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;This function is pure: it has no side effects (assuming &lt;code class="language-plaintext highlighter-rouge"&gt;estimateValueWidth&lt;/code&gt; is a pure function as well). For the same inputs, it will always return the same outputs. So we improved the reliability of our code. Also the next developer that will see this will understand better what it is about, and what is the business rule behind it.&lt;/p&gt; 
&lt;p&gt;Then, we can use this function inside the “old” code:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drawVariation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;drawSparklines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some very long layout and draw logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;And now, we can write unit test for the layout function, as it is a simple JS function.&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score Card Layout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should display only the values&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;INPUT_DATA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WIDTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CHART_OPTIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// etc etc... other tests&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Note that we could go even further and split &lt;code class="language-plaintext highlighter-rouge"&gt;layout&lt;/code&gt; into smaller functions.&lt;/p&gt; 
&lt;p&gt;So in the end, our “new” code is mostly tested. And we have modularized our code a bit. The next developer will understand better the code via this new function, and also via the documentation provided by the tests.&lt;/p&gt; 
&lt;p&gt;Of course it is not perfect: first, we have more code that before. But not much more; and the contribution to the big chart code file has lowered, in the end.&lt;/p&gt; 
&lt;p&gt;Second, what about the drawing functions at the end: &lt;code class="language-plaintext highlighter-rouge"&gt;drawVariation&lt;/code&gt; and &lt;code class="language-plaintext highlighter-rouge"&gt;drawSparklines&lt;/code&gt;? They are not tested, nor in separate modules. It might be difficult to test since we are in a big chart, but we could try!&lt;/p&gt; 
&lt;p&gt;But then, what’s the point? I mean we have tested our business rules (the most important thing to test). If it is easy to test the rest then, ok let’s go ahead.&lt;/p&gt; 
&lt;p&gt;In the end, it depends on:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;how much time we can afford to refactor and test this&lt;/li&gt; 
 &lt;li&gt;how much our tests will prove that the end user will have something working&lt;/li&gt; 
 &lt;li&gt;how much our tests will help the next developer that will have to work on that code&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Using a functional programming approach is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;good for testing small bits of “new” code inside a big chunk of legacy code&lt;/li&gt; 
 &lt;li&gt;improves the reliability and the maintainability of our code&lt;/li&gt; 
 &lt;li&gt;means making functions for complex logic, conditions and arithmetic.&lt;/li&gt; 
 &lt;li&gt;does not solve the fact that you have to adapt and use the result in the legacy code, so you will have to decide if you want to test that or not.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Decorator&lt;/h2&gt; 
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Decorator_pattern"&gt;decorator pattern&lt;/a&gt;, for us, is just a fancy way to say that you’re changing methods of an object at run-time. It can be useful to stub internal methods of your new component. For example, let’s take our login component again, but with a different use case: the dirty SSO.&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Some login component code ...&lt;/span&gt;

  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Some other methods...&lt;/span&gt;
    &lt;span class="nx"&gt;onClickOnLoginWithSSOButton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasSSOActivated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Some very dirty code handling SSO login, that we don't want to test&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;So we want to test that &lt;code class="language-plaintext highlighter-rouge"&gt;legacyLoginWithSSO&lt;/code&gt; is called, but we don’t want the code inside it to be called. In JS we can just do something like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before each test&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLoginWithSSO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// After each test, to avoid side-effects&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLoginWithSSO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;But thankfully, our frameworks and their testing tools already do that for us. For example, with vue it would look like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;

  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;propsData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hasSSOActivated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
        
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should call legacyLoginWithSSO when the user clicks on login with SSO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClickOnLoginWithSSOButton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledOnce&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;In the end, it’s quite simple and we have something tested! You should plan, in the long term, on refactoring the dirty method though.&lt;/p&gt; 
&lt;p&gt;Again, we are not testing &lt;em&gt;everything&lt;/em&gt; here, but we test what’s the most relevant to us: the business rule. So here it is the fact that &lt;code class="language-plaintext highlighter-rouge"&gt;legacyLoginWithSSO&lt;/code&gt; has been called in our context.&lt;/p&gt; 
&lt;p&gt;Note that the test depend on the &lt;code class="language-plaintext highlighter-rouge"&gt;legacyLoginWithSSO&lt;/code&gt; function, wich is (supposidely) somthing internal to the component. You might not want that as it can be more difficult to change and refactor that. But it’s a compromise, as always&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Using decorator is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good for testing “new” code using a small piece of legacy code&lt;/li&gt; 
 &lt;li&gt;Quite simple&lt;/li&gt; 
 &lt;li&gt;Should not hide the fact that you should refactor this small piece of legacy code sometime&lt;/li&gt; 
 &lt;li&gt;Makes our test depend on something internal to the component.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Proxy&lt;/h2&gt; 
&lt;p&gt;How do you do when you need to mock a global object (for example &lt;code class="language-plaintext highlighter-rouge"&gt;window&lt;/code&gt;)? You can use the &lt;a href="https://en.wikipedia.org/wiki/Proxy_pattern"&gt;Proxy pattern&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;This pattern introduces a small level of abstraction between the actual global object and your usage of it in the production code. This level of abstraction can be mocked so you can test that the mock has been called.&lt;/p&gt; 
&lt;p&gt;Let’s say in your production code you need to do something like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;If you have an object like this:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getHref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  
  &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;You can change the production code to&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;You can then stub it in your tests and assert that it has been called:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In before each&lt;/span&gt;
&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Redirection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWindowLocationHrefStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;set&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ToucanComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWindowLocationHrefStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should redirect when the user clicks on the button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.toucan__button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWindowLocationHrefStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Same goes with getters, if in your production code you need to do something like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showPopup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to toucan toco!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;You can add more methods to stub to this Proxy:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getHref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  
  &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;and the production code becomes:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getHref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showPopup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to toucan toco!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;This simple trick allows you to test any global object that you can’t mock easily. It introduces this little Proxy object that only delegates to the actual object. Note that the Proxy should not have too much intelligence, and be as small as possible. Be careful that your proxy does not transform into an hidden utility function; that is not tested.&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Using a proxy object:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;is good for testing global objects,&lt;/li&gt; 
 &lt;li&gt;introduces a level of indirection between your code and the actual object,&lt;/li&gt; 
 &lt;li&gt;should not be seen and used as an utility&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Are you ready?&lt;/h2&gt; 
&lt;p&gt;So now, you don’t have any excuses not to write test, even in your old rotten spaghetti :)&lt;/p&gt; 
&lt;p&gt;There are a lot of other design patterns, programming paradigms or methods out there that you can also use. I just read books and articles, and also experimented a bit myself.&lt;/p&gt; 
&lt;p&gt;While you write your tests, be &lt;em&gt;as pragmatic as possible&lt;/em&gt;. Don’t spend too much or too little time writing your tests. Tests should not be a pain that you address at the end of your coding session. It shouldn’t be something you skip because it looks like a wall that you cannot climb.&lt;/p&gt; 
&lt;p&gt;Tests should be something nice you do during development, while you ask yourself design questions like:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;“Should I refactor this?”&lt;/li&gt; 
 &lt;li&gt;“What are the inputs? and the outputs?”&lt;/li&gt; 
 &lt;li&gt;“What is the expected behaviour?”&lt;/li&gt; 
 &lt;li&gt;“How can I make the code better?” …&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Tests should be part of your journey to make your bug fix or your feature:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you write a fix (even a hotfix), how can prove that the code won’t have bugs again? How can you document your fix for the next developer? It is sure that someone missed something tricky in that particular case.&lt;/li&gt; 
 &lt;li&gt;If you write a feature, how can you prove that it works? How can you make sure that it is the &lt;em&gt;right&lt;/em&gt; design? How can you make sure that the next developer will understand it? How can you document it?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You can answer all of these questions with tests, and methodologies such as TDD; even in legacy code.&lt;/p&gt; 
&lt;p&gt;I did not talk about CSS. I don’t know today how we would do to test such complex logics in CSS (it is possible to do quite complex things with CSS). I know we can use design patterns such as BEM or SMACCS or … But I don’t know if we can test it, or at least test the logic behind it. In Toucan Toco, we try to have very simple BEM CSS, and don’t add too much conditions and inheritance in our CSS. We assert on the classes of the DOM set by the JS code. It is not ideal, but we’re happy with it for now.&lt;/p&gt; 
&lt;p&gt;I also did not talk about other kind of tests: multi-component, service, e2e. Similar patterns can be used to do this kind of tests in legacy code. Keep in mind the &lt;a href="https://martinfowler.com/articles/practical-test-pyramid.html"&gt;Pragmatical Test Pyramid&lt;/a&gt;: test what makes sense to be tested, careful with the cost.&lt;/p&gt; 
&lt;p&gt;To finish, design patterns make a great toolbox that can be used for many other problems that you might encounter as a developer. I have used it many times in my career and even though they seem a bit Object-Oriented, you can still apply some concepts to javascript (and other languages). They come from the fact that we are not the first ones to have this kind of problems in programming, and many before us have solved this problems; maybe with other languages. But still, we can benefit a lot from this knowledge.&lt;/p&gt; 
&lt;p&gt;It is true that some of the methodologies explained here seem quite difficult to apply; but refactoring reflexes in legacy code is not easy but it comes with training and experience. I encourage you to do some programming Katas or Dojos, to train yourself at this craftsmanship, experiment and be better and better. When you master this, you can then mentor Juniors in your company and make sure that your code will be maintainable in the very-long run.&lt;/p&gt;  
&lt;p&gt;Sources:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;“Test-Driven Development by Example” - Kent Beck&lt;/li&gt; 
 &lt;li&gt;“Working Effectively with Legacy Code” - Michael C. Feathers&lt;/li&gt; 
 &lt;li&gt;“The Clean Coder” - Robert C. Martin&lt;/li&gt; 
 &lt;li&gt;Refactoring - Martin Fowler&lt;/li&gt; 
 &lt;li&gt;Martin Fowler’s blog: https://martinfowler.com&lt;/li&gt; 
 &lt;li&gt;Wikipedia’s &lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern"&gt;design pattern page&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/patterns-unit-testing" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/we-dont-test-that-2.webp" alt="Test any code, even the code you are not proud of | Toucan Toco" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;A pragmatic approach to unit testing in legacy code (code that people think isn’t testable and that nobody wants to touch anymore). Using simple mocks and design patterns, in javascript.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;h2&gt;Once upon a time…&lt;/h2&gt; 
&lt;p&gt;Have you ever heard something like:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“It’s ok, we don’t test that code.”&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“Are you sure you want to touch that code? You might break something.”&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Sounds familiar no? Usually, it even refers to the same code.&lt;/p&gt; 
&lt;p&gt;Testing in “good” code is &lt;a href="https://vue-test-utils.vuejs.org/guides/#test-rendered-html-output-of-the-component"&gt;really easy&lt;/a&gt;. Just follow the documentation! By “good” code, I mean:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Code that everyone in your team understands (readability)&lt;/li&gt; 
 &lt;li&gt;Code that everyone in your team loves to contribute to, and they do it very fast (maintainability)&lt;/li&gt; 
 &lt;li&gt;Code that everyone in your team &lt;em&gt;agrees&lt;/em&gt; on (best practices, conventions)&lt;/li&gt; 
 &lt;li&gt;If you use a library / framework: 
  &lt;ul&gt; 
   &lt;li&gt;the library / framework is recent (or at least it is still maintained)&lt;/li&gt; 
   &lt;li&gt;it is quite common (today: VueJS, React, Angular…), or at least uses common concepts so that you can on-board new devs on it easily&lt;/li&gt; 
   &lt;li&gt;the code follows the common patterns and practices of this library / framework&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Luckily for us we have all these libraries/frameworks that (supposedly) make our life very easy. But let’s remember again, have you ever heard something like:&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;“Use framework/tool XXXX you will see, it is so awesome, it’s going to work perfectly!! You’re going to love it!&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;And then you’re like&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Ok XXXX seems great! I’m going to start using it all over the place, wohooo!&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Some weeks later&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Oh I have to do this feature very fast, let’s just do this small hack, by using this dark feature of the framework. It’s ok, temporarily. (…)&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;We’re so late! We will write tests later.&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Over the weeks, people have extracted this code into an utility and is used in 10% of your 100 000 lines of code app.&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;Let’s upgrade XXXX! (…) Oh my god, what have we done? This is going to take months!&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;So I bet that all your code is not “good” code, and that you have to deal with legacy code (as most developers have to). If you don’t think you have legacy code, I am pretty sure you are going to change your mind in a couple of months.&lt;/p&gt; 
&lt;p&gt;That is because most code have an expiration date, more or less in the future. No one can escape that. We are humans, we are limited, we have to take difficult decisions. We have to think about the long term in a very fast changing environment. And sometimes, we make small mistakes. Overtime, these mistakes accumulate to make a mess. But I think it is OK. We have to accept that &lt;em&gt;the code we write today is the legacy code of tomorrow&lt;/em&gt;.&lt;/p&gt; 
&lt;p&gt;But we can still &lt;em&gt;improve&lt;/em&gt; this code. Even if your code has expired for so long that’s it’s become a rotten spaghetti monster. The one that smells so bad that you are really afraid of it, you avoid touching any of it, and you dream of trashing it once and for all.&lt;/p&gt; 
&lt;p&gt;So let’s start to “Make &lt;em&gt;your code&lt;/em&gt; great again”!&lt;/p&gt; 
&lt;p&gt;How do you do that? There are already well known community-approved solutions:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Tests (and related methodologies such as TDD)&lt;/li&gt; 
 &lt;li&gt;Thorough code reviews&lt;/li&gt; 
 &lt;li&gt;Pair programing, mob programming or other kind of group work&lt;/li&gt; 
 &lt;li&gt;Domain Driven Design&lt;/li&gt; 
 &lt;li&gt;“Slack time” to refactor&lt;/li&gt; 
 &lt;li&gt;Zero bug policy&lt;/li&gt; 
 &lt;li&gt;…&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;This article focuses on &lt;em&gt;unit tests&lt;/em&gt;. I think tests are one of the most difficult thing to do with legacy code. But it’s one of the most important things to do. Sadly, it’s also one of the things that is often put aside, especially in front end development.&lt;/p&gt; 
&lt;p&gt;Tests allows you to:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;em&gt;prove&lt;/em&gt; that your code works as expected for your end user&lt;/li&gt; 
 &lt;li&gt;explain your code to the next developer that will have to maintain it&lt;/li&gt; 
 &lt;li&gt;have better technical designs by forcing you to isolate logical units (so you can test them)&lt;/li&gt; 
 &lt;li&gt;write exhaustive functional specifications of your component (made explicit by tests titles, like “it should do this”)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;I will talk more about why we should test in another article.&lt;/p&gt; 
&lt;p&gt;We will see that there are a lot of choices that we will have to do while writing tests. But one thing should help us make those choices: we should &lt;em&gt;be as pragmatic as possible&lt;/em&gt; in our test strategy.&lt;/p&gt; 
&lt;p&gt;We want to spend only the time we can afford to on those tests: not a few seconds, nor a few months. Just the time needed to write tests in our new code so that the following can be achieved :&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;the tests prove that what’s important for the end user will work&lt;/li&gt; 
 &lt;li&gt;the tests explain the logic behind your code for the next developer that will have to change it&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;We also want to test &lt;em&gt;only&lt;/em&gt; your new code. We don’t want to take months to refactor the entire existing codebase and write unit tests for all of it. We’re taking a pragmatic incremental approach: &lt;em&gt;every new logic should be tested&lt;/em&gt;. We don’t want to test libraries or tools either: for exemple, we trust that the browser will display a &lt;code class="language-plaintext highlighter-rouge"&gt;&amp;lt;div&amp;gt;&lt;/code&gt; correctly.&lt;/p&gt; 
&lt;p&gt;Of course you can spend more time &lt;em&gt;if you can afford it&lt;/em&gt;. You will then refactor more, test more existing code. That will lead to: better designs, exhaustive functional specifications… But be careful; you also want to deliver functionality to you end users. Think about what’s best for them and for your team.&lt;/p&gt; 
&lt;p&gt;So let’s start to write tests! Every section below contains a pragmatic approach to test in legacy code; at the end of each section, a recap sums up the pros and cons of the approach.&lt;/p&gt; 
&lt;h2&gt;Use the framework!&lt;/h2&gt; 
&lt;p&gt;If the code you want to contribute to uses a framework that supports testing, just follow the documentation of this framework! But I think that if you are reading this, you have to deal with a tricky codebase that have old frameworks or old code that is hardly testable.&lt;/p&gt; 
&lt;p&gt;If you want to create a component or add much functionality to an existing component, you can just refactor directly into a “new” framework. And it’s feasible, using the &lt;a href="https://en.wikipedia.org/wiki/Adapter_pattern"&gt;Adapter&lt;/a&gt; design pattern (also called wrapper).&lt;/p&gt; 
&lt;p&gt;As an example, I recently updated the design of the login page in the Toucan Toco front end. Because the login page is one of the first thing you have to do when you make a front end, the code was an old AngularJS mess. I re-wrote the component with TDD in less than one week, in VueJS, using an Adapter.&lt;/p&gt; 
&lt;p&gt;The adapter between vueJS and AngularJS looks like this:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// The vue component&lt;/span&gt;

&lt;span class="nx"&gt;angular&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loginNg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;restrict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;E&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div class="login__vue-placeholder"&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginWrapperVm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.login__vue-placeholder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// 1. Insertion in the DOM&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login-wrapper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;authenticationManager&lt;/span&gt; &lt;span class="c1"&gt;// 3. Adaptation of an old angular service&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$destroy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;loginWrapperVm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$destroy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 2. Adaptation of 'destroy' lifecycle.&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;We will talk about our approach to incremental refactoring from AngularJS to VueJS in another article (coming up soon).&lt;/p&gt; 
&lt;p&gt;This adapter has the role to adapt the AngularJS API to the VueJS API. We can see three interesting adaptations:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;The insertion in the DOM&lt;/li&gt; 
 &lt;li&gt;The destroy lifecycle&lt;/li&gt; 
 &lt;li&gt;The authenticationManager service&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;The authenticationManager service is particularly interesting. I wanted to change the Login page was designed, not the way that all the login and authentication works.&lt;/p&gt; 
&lt;p&gt;This AngularJS service deals with many aspects of authentication in the app. My first thought was to refactor it as well. But it is a very complex class (400 lines of code) with a lot of state hidden inside. It is also used widely in different parts of the legacy code: I would have had to refactor that as well. So refactoring would have been very difficult, and instead of a week, it would have taken a month.&lt;/p&gt; 
&lt;p&gt;But injection comes to our rescue! When you want to partially refactor a component without changing all the code that depends on this component, you can just inject the “old” objects that have to be called from your refactored code. For our Login VueJS component, it goes like this:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="na"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authenticationManager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;// Some login component code ...&lt;/span&gt;

  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      
    &lt;span class="c1"&gt;// Some other methods ... &lt;/span&gt;
    
    &lt;span class="nx"&gt;performLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// HTTP call to the API&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLoginSuccessful&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Call to the legacy angular service dealing with authentication&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Many frameworks support injection, or similar mechanisms. Worst case scenario, you can pass your legacy APIs as object parameters of your component. You could even export a function that creates or returns the current instance of your legacy JS service (see the factory section).&lt;/p&gt; 
&lt;p&gt;Anyway, with that we have brand-new code using our “modern” framework and we’re happy. We know how to test it. But how do we test the Adapter? and the injection? Sadly, you can’t. You can only test that the injected object is called correctly in the new code:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;

  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockAuthenticationManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;onLoginSuccessful&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;authenticationManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockAuthenticationManager&lt;/span&gt; 
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
        
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when the user inputs his username and his password, and then clicks login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... Set the username, password and clicks login ...&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should notify the authentication manager of the successful login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert that the legacy API have been called &lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockAuthenticationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLoginSuccessful&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USERNAME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOGIN_RESPONSE_DATA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;But it’s OK it’s just a few lines of code without any business rules (see my article on “What to test?”). It’s mostly boiler plate framework-code that we don’t really &lt;em&gt;care&lt;/em&gt; about. If it breaks, you will notice it pretty fast (the login page will not display). Also, it could be tested via multi-component tests or end-to-end tests.&lt;/p&gt; 
&lt;p&gt;Most of the times &lt;em&gt;you have to take pragmatic choices, and put things into perspective&lt;/em&gt;. The code is in better shape than before now (it follows conventions), and we have increased test coverage. But it is true that it is not &lt;em&gt;perfect&lt;/em&gt; and we introduced a new piece of code (the adapter) that is not tested, and does not follow the best practices of AngularJS nor VueJS. Also, it required a bit of work; that you might not have the time to do.&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;To sum up, the adapter:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;good to transform a significant piece of legacy code with an old framework into “new” code with a “modern” framework that you can test&lt;/li&gt; 
 &lt;li&gt;uses an adaptation code between the two frameworks&lt;/li&gt; 
 &lt;li&gt;uses injection for the pieces of code you don’t want to refactor (yet)&lt;/li&gt; 
 &lt;li&gt;requires a bit of work&lt;/li&gt; 
 &lt;li&gt;adds some code (the adapter) that we do not test&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;(Sort-of) Factory&lt;/h2&gt; 
&lt;p&gt;Let’s talk about the other cool trick that we have talked about in the previous section: the sort-of &lt;a href="https://en.wikipedia.org/wiki/Factory_method_pattern"&gt;Factory Pattern&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;Factories are very useful to inject mock-objects at run-time for your tests. They also help you modularize your code. For example, let’s say we are in a chart component, and we want to add a new parameter to the chart legend.&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  
  &lt;span class="c1"&gt;// ... Some existing D3 JS code ...&lt;/span&gt;
  
  &lt;span class="c1"&gt;// This the new parameter that we want to test&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="c1"&gt;// Existing legacy code for the legend&lt;/span&gt;
  &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.my-chart__legend-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Not easily testable code (for some reason)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;makeExtraInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// More complex untestable code that depend on displayExtraInformation...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Let’s also say the code in the &lt;code class="language-plaintext highlighter-rouge"&gt;text&lt;/code&gt; callback is not easily testable (for some reason). So it is hard to test independently when &lt;code class="language-plaintext highlighter-rouge"&gt;displayExtraInformation&lt;/code&gt; is true or not. You could export a getter to this boolean if you make it global, but then it won’t be a &lt;code class="language-plaintext highlighter-rouge"&gt;const&lt;/code&gt; anymore and it would degrade the design by putting the variable as a ‘state’ variable. Also, it’s a lot of modifications that does not necessarily clarify the code.&lt;/p&gt; 
&lt;p&gt;Let’s see if we can separate the legend in a different module (which make sense, it is a different component, functionally):&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charts/legend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  
  &lt;span class="c1"&gt;// ... Some existing D3 JS code ...&lt;/span&gt;
  
  &lt;span class="c1"&gt;// This is the new code that we want to test&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  
  &lt;span class="c1"&gt;// New function !&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Other parameters..&lt;/span&gt;
    &lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  
  &lt;span class="c1"&gt;// Wiring to the legacy&lt;/span&gt;
  &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.my-chart__legend-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myChartLegend&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ... other D3 JS code ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;and in ‘charts/legend/index.js’:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;selection&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Not easily testable code (for some reason)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;makeExtraInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// More complex untestable code that depend on displayExtraInformation...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Now we can stub the &lt;code class="language-plaintext highlighter-rouge"&gt;createChartLegend&lt;/code&gt; and assert the call in our tests! Using the import syntax we have the following:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sinon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charts/my-chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ChartLegendFactory&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;charts/legend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;


&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    
  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartLegendFactoryStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ChartLegendFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartLegendFactoryStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should call the chartLegendFactory with displayExtraInformation as true when the chart is large enough&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drawMyChart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartLegendFactoryStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
    
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;If we didnt want to separate the chart legend in a seperate module, we would have done the following:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only used for testing&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setChartLegendFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;oldFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;oldFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;createChartLegend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;displayExtraInformation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Same as before&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawMyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasFilters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// same as before&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;We would call &lt;code class="language-plaintext highlighter-rouge"&gt;setChartLegendFactory&lt;/code&gt; in &lt;code class="language-plaintext highlighter-rouge"&gt;beforeEach&lt;/code&gt;&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createChartStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLegendFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setChartLegendFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createChartStub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;And reinitialize it in &lt;code class="language-plaintext highlighter-rouge"&gt;afterEach&lt;/code&gt;, to avoid side-effects:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setChartLegendFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLegendFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Note that this adds some code (here, the &lt;code class="language-plaintext highlighter-rouge"&gt;setChartLegendFactory&lt;/code&gt; function) that is only used for test. It is quite common practice to open some functions or attributes only for testing purposes. Some may argue that it degrades the design of your code, but it is sometimes the most efficient way to be able to test something. I would use it as a &lt;em&gt;last resort&lt;/em&gt; when you don’t know how to do otherwise. But if you can inject your object using a clean technique that does not impact your production code, then you should do that instead.&lt;/p&gt; 
&lt;p&gt;You can also use the factory pattern to inject old legacy code into a new piece of code as we talked about in the Adapter section.&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;The (sort-of) factory pattern is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;good for testing small bits of “new” code calling the legacy code&lt;/li&gt; 
 &lt;li&gt;gives you the ability to inject objects or functions at run-time&lt;/li&gt; 
 &lt;li&gt;usually, this means mocking the legacy code&lt;/li&gt; 
 &lt;li&gt;also useful to inject legacy services into “new” code&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Functional programing&lt;/h2&gt; 
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Functional_programming"&gt;Functional programing&lt;/a&gt; is not a design pattern itself, but a paradigm we can follow to help us test our “new” code. We can see it as a programing style: make everything stateless functions. How can you achieve that? Simple:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt;Identify a block of code with business logic in it (a bunch of &lt;code class="language-plaintext highlighter-rouge"&gt;if&lt;/code&gt;, &lt;code class="language-plaintext highlighter-rouge"&gt;else&lt;/code&gt;s, and calculus). If the block is not clear, try to group the lines of code that seem independent.&lt;/li&gt; 
 &lt;li&gt;Identify the inputs and outputs of this block of code. Typically, input variables are variables used at the right of &lt;code class="language-plaintext highlighter-rouge"&gt;=&lt;/code&gt; and output are new variables declared at the left of &lt;code class="language-plaintext highlighter-rouge"&gt;=&lt;/code&gt;, and used later in the code.&lt;/li&gt; 
 &lt;li&gt;For the state-dependent variables, the same rule applies.&lt;/li&gt; 
 &lt;li&gt;Declare the outputs clearly at the end of your block of code.&lt;/li&gt; 
 &lt;li&gt;Create a separate function where parameters of this function are the inputs and the function returns an object containing all the outputs.&lt;/li&gt; 
 &lt;li&gt;Put the block of code into this new function; rename the variables if you have to.&lt;/li&gt; 
 &lt;li&gt;Call this function where the block of code was.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Got it? Let’s try that in practice. So our example is a D3 chart, and we want to change some part of the layout of this chart. Sadly, this chart is in legacy code, and not tested. We have an existing function &lt;code class="language-plaintext highlighter-rouge"&gt;scope.update&lt;/code&gt;; that does all the layout, and that is very long&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ... Some chart stuff ...&lt;/span&gt;
&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    
  &lt;span class="nx"&gt;drawVariation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;drawSparklines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  
  &lt;span class="c1"&gt;// ... some very long layout and draw logic&lt;/span&gt;
  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;So we add our new layout code, not refactored (yet):&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ... Some chart code...&lt;/span&gt;
&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;estimateValueWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variationSignWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklineWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drawVariation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;drawSparklines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some very long layout and draw logic un angular JS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Using the methodology I talked about before, we can clearly identify a block of code that &lt;em&gt;looks&lt;/em&gt; functional: the beginning of the code. It is pure math and assignments.&lt;/p&gt; 
&lt;p&gt;The inputs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;inputData&lt;/code&gt; array&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;chartOptions&lt;/code&gt; object&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;config&lt;/code&gt; object&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;width&lt;/code&gt; number&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;And the outputs:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;the boolean &lt;code class="language-plaintext highlighter-rouge"&gt;shouldDisplaySparklines&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;the boolean &lt;code class="language-plaintext highlighter-rouge"&gt;shouldDisplayVariation&lt;/code&gt;&lt;/li&gt; 
 &lt;li&gt;the &lt;code class="language-plaintext highlighter-rouge"&gt;estimatedVariationWidth&lt;/code&gt; number&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;With that in mind, let’s create the prototype of our function:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;We named it &lt;code class="language-plaintext highlighter-rouge"&gt;layout&lt;/code&gt; after seeing the inputs and outputs: it has clearly something to do with &lt;code class="language-plaintext highlighter-rouge"&gt;layout&lt;/code&gt;.&lt;/p&gt; 
&lt;p&gt;So now, copy paste our functional code block, renaming the variables a bit:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;estimateValueWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variationSignWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sparklineWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;This function is pure: it has no side effects (assuming &lt;code class="language-plaintext highlighter-rouge"&gt;estimateValueWidth&lt;/code&gt; is a pure function as well). For the same inputs, it will always return the same outputs. So we improved the reliability of our code. Also the next developer that will see this will understand better what it is about, and what is the business rule behind it.&lt;/p&gt; 
&lt;p&gt;Then, we can use this function inside the “old” code:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chartOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drawVariation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;estimatedVariationWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;drawSparklines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some very long layout and draw logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;And now, we can write unit test for the layout function, as it is a simple JS function.&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score Card Layout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should display only the values&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;INPUT_DATA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WIDTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CHART_OPTIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplaySparklines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shouldDisplayVariation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// etc etc... other tests&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Note that we could go even further and split &lt;code class="language-plaintext highlighter-rouge"&gt;layout&lt;/code&gt; into smaller functions.&lt;/p&gt; 
&lt;p&gt;So in the end, our “new” code is mostly tested. And we have modularized our code a bit. The next developer will understand better the code via this new function, and also via the documentation provided by the tests.&lt;/p&gt; 
&lt;p&gt;Of course it is not perfect: first, we have more code that before. But not much more; and the contribution to the big chart code file has lowered, in the end.&lt;/p&gt; 
&lt;p&gt;Second, what about the drawing functions at the end: &lt;code class="language-plaintext highlighter-rouge"&gt;drawVariation&lt;/code&gt; and &lt;code class="language-plaintext highlighter-rouge"&gt;drawSparklines&lt;/code&gt;? They are not tested, nor in separate modules. It might be difficult to test since we are in a big chart, but we could try!&lt;/p&gt; 
&lt;p&gt;But then, what’s the point? I mean we have tested our business rules (the most important thing to test). If it is easy to test the rest then, ok let’s go ahead.&lt;/p&gt; 
&lt;p&gt;In the end, it depends on:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;how much time we can afford to refactor and test this&lt;/li&gt; 
 &lt;li&gt;how much our tests will prove that the end user will have something working&lt;/li&gt; 
 &lt;li&gt;how much our tests will help the next developer that will have to work on that code&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Using a functional programming approach is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;good for testing small bits of “new” code inside a big chunk of legacy code&lt;/li&gt; 
 &lt;li&gt;improves the reliability and the maintainability of our code&lt;/li&gt; 
 &lt;li&gt;means making functions for complex logic, conditions and arithmetic.&lt;/li&gt; 
 &lt;li&gt;does not solve the fact that you have to adapt and use the result in the legacy code, so you will have to decide if you want to test that or not.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Decorator&lt;/h2&gt; 
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Decorator_pattern"&gt;decorator pattern&lt;/a&gt;, for us, is just a fancy way to say that you’re changing methods of an object at run-time. It can be useful to stub internal methods of your new component. For example, let’s take our login component again, but with a different use case: the dirty SSO.&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Some login component code ...&lt;/span&gt;

  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Some other methods...&lt;/span&gt;
    &lt;span class="nx"&gt;onClickOnLoginWithSSOButton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasSSOActivated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Some very dirty code handling SSO login, that we don't want to test&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;So we want to test that &lt;code class="language-plaintext highlighter-rouge"&gt;legacyLoginWithSSO&lt;/code&gt; is called, but we don’t want the code inside it to be called. In JS we can just do something like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before each test&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLoginWithSSO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// After each test, to avoid side-effects&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;originalLoginWithSSO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;But thankfully, our frameworks and their testing tools already do that for us. For example, with vue it would look like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;

  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;propsData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hasSSOActivated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
        
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should call legacyLoginWithSSO when the user clicks on login with SSO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClickOnLoginWithSSOButton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;legacyLoginWithSSO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledOnce&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;In the end, it’s quite simple and we have something tested! You should plan, in the long term, on refactoring the dirty method though.&lt;/p&gt; 
&lt;p&gt;Again, we are not testing &lt;em&gt;everything&lt;/em&gt; here, but we test what’s the most relevant to us: the business rule. So here it is the fact that &lt;code class="language-plaintext highlighter-rouge"&gt;legacyLoginWithSSO&lt;/code&gt; has been called in our context.&lt;/p&gt; 
&lt;p&gt;Note that the test depend on the &lt;code class="language-plaintext highlighter-rouge"&gt;legacyLoginWithSSO&lt;/code&gt; function, wich is (supposidely) somthing internal to the component. You might not want that as it can be more difficult to change and refactor that. But it’s a compromise, as always&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Using decorator is:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;Good for testing “new” code using a small piece of legacy code&lt;/li&gt; 
 &lt;li&gt;Quite simple&lt;/li&gt; 
 &lt;li&gt;Should not hide the fact that you should refactor this small piece of legacy code sometime&lt;/li&gt; 
 &lt;li&gt;Makes our test depend on something internal to the component.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Proxy&lt;/h2&gt; 
&lt;p&gt;How do you do when you need to mock a global object (for example &lt;code class="language-plaintext highlighter-rouge"&gt;window&lt;/code&gt;)? You can use the &lt;a href="https://en.wikipedia.org/wiki/Proxy_pattern"&gt;Proxy pattern&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;This pattern introduces a small level of abstraction between the actual global object and your usage of it in the production code. This level of abstraction can be mocked so you can test that the mock has been called.&lt;/p&gt; 
&lt;p&gt;Let’s say in your production code you need to do something like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;If you have an object like this:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getHref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  
  &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;You can change the production code to&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;You can then stub it in your tests and assert that it has been called:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In before each&lt;/span&gt;
&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Redirection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWindowLocationHrefStub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sinon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;set&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shallowMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ToucanComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWindowLocationHrefStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should redirect when the user clicks on the button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.toucan__button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWindowLocationHrefStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;been&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;Same goes with getters, if in your production code you need to do something like:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showPopup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to toucan toco!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;You can add more methods to stub to this Proxy:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getHref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  
  &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;and the production code becomes:&lt;/p&gt; 
&lt;div class="language-javascript highlighter-rouge"&gt; 
 &lt;div class="highlight"&gt; 
  &lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WindowLocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getHref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://toucantoco.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showPopup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to toucan toco!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;This simple trick allows you to test any global object that you can’t mock easily. It introduces this little Proxy object that only delegates to the actual object. Note that the Proxy should not have too much intelligence, and be as small as possible. Be careful that your proxy does not transform into an hidden utility function; that is not tested.&lt;/p&gt; 
&lt;h3&gt;Conclusion&lt;/h3&gt; 
&lt;p&gt;Using a proxy object:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;is good for testing global objects,&lt;/li&gt; 
 &lt;li&gt;introduces a level of indirection between your code and the actual object,&lt;/li&gt; 
 &lt;li&gt;should not be seen and used as an utility&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Are you ready?&lt;/h2&gt; 
&lt;p&gt;So now, you don’t have any excuses not to write test, even in your old rotten spaghetti :)&lt;/p&gt; 
&lt;p&gt;There are a lot of other design patterns, programming paradigms or methods out there that you can also use. I just read books and articles, and also experimented a bit myself.&lt;/p&gt; 
&lt;p&gt;While you write your tests, be &lt;em&gt;as pragmatic as possible&lt;/em&gt;. Don’t spend too much or too little time writing your tests. Tests should not be a pain that you address at the end of your coding session. It shouldn’t be something you skip because it looks like a wall that you cannot climb.&lt;/p&gt; 
&lt;p&gt;Tests should be something nice you do during development, while you ask yourself design questions like:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;“Should I refactor this?”&lt;/li&gt; 
 &lt;li&gt;“What are the inputs? and the outputs?”&lt;/li&gt; 
 &lt;li&gt;“What is the expected behaviour?”&lt;/li&gt; 
 &lt;li&gt;“How can I make the code better?” …&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Tests should be part of your journey to make your bug fix or your feature:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;If you write a fix (even a hotfix), how can prove that the code won’t have bugs again? How can you document your fix for the next developer? It is sure that someone missed something tricky in that particular case.&lt;/li&gt; 
 &lt;li&gt;If you write a feature, how can you prove that it works? How can you make sure that it is the &lt;em&gt;right&lt;/em&gt; design? How can you make sure that the next developer will understand it? How can you document it?&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;You can answer all of these questions with tests, and methodologies such as TDD; even in legacy code.&lt;/p&gt; 
&lt;p&gt;I did not talk about CSS. I don’t know today how we would do to test such complex logics in CSS (it is possible to do quite complex things with CSS). I know we can use design patterns such as BEM or SMACCS or … But I don’t know if we can test it, or at least test the logic behind it. In Toucan Toco, we try to have very simple BEM CSS, and don’t add too much conditions and inheritance in our CSS. We assert on the classes of the DOM set by the JS code. It is not ideal, but we’re happy with it for now.&lt;/p&gt; 
&lt;p&gt;I also did not talk about other kind of tests: multi-component, service, e2e. Similar patterns can be used to do this kind of tests in legacy code. Keep in mind the &lt;a href="https://martinfowler.com/articles/practical-test-pyramid.html"&gt;Pragmatical Test Pyramid&lt;/a&gt;: test what makes sense to be tested, careful with the cost.&lt;/p&gt; 
&lt;p&gt;To finish, design patterns make a great toolbox that can be used for many other problems that you might encounter as a developer. I have used it many times in my career and even though they seem a bit Object-Oriented, you can still apply some concepts to javascript (and other languages). They come from the fact that we are not the first ones to have this kind of problems in programming, and many before us have solved this problems; maybe with other languages. But still, we can benefit a lot from this knowledge.&lt;/p&gt; 
&lt;p&gt;It is true that some of the methodologies explained here seem quite difficult to apply; but refactoring reflexes in legacy code is not easy but it comes with training and experience. I encourage you to do some programming Katas or Dojos, to train yourself at this craftsmanship, experiment and be better and better. When you master this, you can then mentor Juniors in your company and make sure that your code will be maintainable in the very-long run.&lt;/p&gt;  
&lt;p&gt;Sources:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;“Test-Driven Development by Example” - Kent Beck&lt;/li&gt; 
 &lt;li&gt;“Working Effectively with Legacy Code” - Michael C. Feathers&lt;/li&gt; 
 &lt;li&gt;“The Clean Coder” - Robert C. Martin&lt;/li&gt; 
 &lt;li&gt;Refactoring - Martin Fowler&lt;/li&gt; 
 &lt;li&gt;Martin Fowler’s blog: https://martinfowler.com&lt;/li&gt; 
 &lt;li&gt;Wikipedia’s &lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern"&gt;design pattern page&lt;/a&gt;.&lt;/li&gt; 
&lt;/ul&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2Fpatterns-unit-testing&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Tue, 19 Mar 2019 04:00:00 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/patterns-unit-testing</guid>
      <dc:date>2019-03-19T04:00:00Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
    <item>
      <title>Why I chose Toucan Toco after 15 years in another company</title>
      <link>https://www.toucantoco.com/en/tech-blog/3months-at-toucan</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/3months-at-toucan" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/values-baloo-necessities-2.webp" alt="Why I chose Toucan Toco after 15 years in another company" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The aim of this article is to explain why I decided to apply for Toucan Toco&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;During the last few days, I’ve been asked a bunch of times by my workmates how I was feeling about my work @Toucan. I thought that it was time to take a few minutes to answer here and share some information with the outside world (or just with my last-year-self).&lt;/p&gt; 
&lt;h2&gt;Why did I choose ToucanToco ?&lt;/h2&gt; 
&lt;p&gt;I learned about Toucan Toco during some casual talks at &lt;a href="http://www.openvisconf.com/"&gt;OpenVis&lt;/a&gt;. A few weeks later, after having read the company’s blog posts and checked the product, I was impressed by the fact that the company grew that fast — 70 persons after 4 years — while being self-financed. The product seemed beautiful and easy to use, the technical stack (python / pandas / vuejs / d3js / ansible) was familiar yet motivating.&lt;/p&gt; 
&lt;p&gt;Besides the technical points, I also got the feeling that human factors, organisations and structural questions (agility, holacracy, core values, inclusion) were first-class citizens and this was a big motivator for me so I decided to apply.&lt;/p&gt; 
&lt;h2&gt;Onboarding&lt;/h2&gt; 
&lt;p&gt;I stayed more than 15 years — and it was a nice and rich experience! — in my previous company, so I was a bit skeptical about how long it would take me to get familiar with the code, product and internal processes. But no worries, Toucan has your back and you’ll be up and running very quickly!&lt;/p&gt; 
&lt;p&gt;Whether you are a developer, a sales person or a client success manager, chances are that you’ll have to get accustomed to your new &lt;a href="https://blog.trello.com/how-toucan-toco-used-trello-to-collaborate-with-ubisoft"&gt;Trello&lt;/a&gt; friend. We use it daily to organize and synchronize personal and team work. More specifically, Toucan Toco has crafted specific “onboarding boards” for each job. Each board defines a set of cards that should be completed during the first 2 months. These tasks range from very basic tasks such as “configure your slack profile” to specific development tasks such as “make a pull request on the product documentation” and more general ones such as “take part to a sales meeting”. These tasks are themselves organized week by week and provide a soft canvas that follows naturally your progression in the company. During all the process, another employee will mentor and will meet you at least once a week to provide feedback and help you finding your path in this welcoming, yet sometimes overwhelming environment.&lt;/p&gt; 
&lt;p&gt;From my point of view, it was a nice experience that helped me to quickly grasp the various tools, processes and cultural specificities of the company. I’ve heard a few of my colleagues say that it might be too heavy of a process. I concede that the number of trello cards is a bit frightening &lt;em&gt;but&lt;/em&gt; I do think it’s a very efficient way to ramp up and incite you to communicate with other teams (developers and sales talk together!) in a very comfy frame. For instance, during the first week — which passes through very quickly considering all the administrative tasks to perform, your laptop and tools to configure, etc. — I think I had already submitted a pull request on the product and reviewed a few which means that some of my code was in production on week 2, not so bad, huh? And I definitely attribute this “performance” to the onboarding process rather than to my personal skills.&lt;/p&gt;  
&lt;p&gt;Another achievement is that even if I’m definitely not fluent technically on all topics, I do think I would now be able to mentor a newcomer after only 3 months here.&lt;/p&gt; 
&lt;h2&gt;5 core values&lt;/h2&gt; 
&lt;p&gt;The onboarding process was also definitely a way to test how the &lt;a href="https://toucantoco.com/en/team.html#values"&gt;5 core values&lt;/a&gt; are spread through the company. &lt;em&gt;WTFM&lt;/em&gt; is clearly not an empty word: there is &lt;em&gt;a lot&lt;/em&gt; of documentation (technical, organisational, logbooks…). Of course the downside is to keep this documentation up-to-date but it’s a continuous and common effort and the onboarding period is clearly a good one to check if documentation matches reality (&lt;em&gt;spoiler&lt;/em&gt;: no… but everyone is encouraged to fix it!). One of the other core value &lt;em&gt;Be well and take care&lt;/em&gt; would be my personal favorite: 75 individuals, a lot of small teams, sometimes very solid, different perspectives, affinity, but despite this variety, I have the feeling that everyone tries hard to be benevolent and keep an inclusive mindset towards others, especially newcomers.&lt;/p&gt; 
&lt;p&gt;The recruitment process was also in retrospect a nice expression of Toucan Toco’s values. I felt sincere benevolence and care during the (admittedly a bit long) list of interviews. A candidate recently even thanked Toucan Toco on twitter despite its application dismissal. My technical skill test was 2-folded. First, I had to talk about a piece of software I had written (design or technical choices). I then took part to a “Technical enhancement Proposal” meeting, (e.g. &lt;a href="https://www.python.org/dev/peps/"&gt;PEP-like&lt;/a&gt; meeting for internal technical subjects). All ideas were listened to, each participant in the discussion — hopefully including me — had the chance to bring up relevant inputs (&lt;em&gt;Each one teach one&lt;/em&gt;, the 2nd core-value, Bingo!).&lt;/p&gt; 
&lt;p&gt;Core values are often emphasized on companies’ websites but they often sound shallow. After three months here, I’m happy to say that those core values are not a set of buzzwords. They’re regulary challenged and have even changed — the curious will dig the web — to better match the actual state of mind of the company.&lt;/p&gt; 
&lt;h2&gt;Constant feedback&lt;/h2&gt; 
&lt;p&gt;Continuing along with &lt;em&gt;Each one teach one&lt;/em&gt; at Toucan, the cultural fit is also spread through a few ceremonies. Besides the traditional weekly team retrospectives, there are 2 monthly events:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;the “monthly news meeting”: each team in the company explains last month’s successes, failures and its updated roadmap. In my brief experience here, it’s a key event to share the global vision across all the company. This event is always a good place to keep everyone sync’ed and to deeply reinstate how each team’s objectives converge towards the same goal. It can be a very good motivator (often followed by a casual drink, which is always nice, just saying…),&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;the “product showcase”: the dev teams share with all other teams, during an hour, what was developed and shipped in the past month. We’re a “product-driven” company and this is where developers have a chance to shine. Each other team must leave that meeting confident that we’re making steady progress. We must share our vision, prove we’ve taken their feedback and keep on innovating.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Aligned autonomy and room for improvement&lt;/h2&gt; 
&lt;p&gt;During my short time here, I was under the impression that our retrospectives did not capture enough some aspects of “human / organizational” topics. I thus proposed &lt;a href="https://labs.spotify.com/2014/09/16/squad-health-check-model/"&gt;specific workshops&lt;/a&gt; in the back-end team. It seemed convincing enough for the “front-end” team to try it. Now, the “project delivery” team will itself try it in a few days. I even had someone at the sales team asking me for more information about the workshop.&lt;/p&gt; 
&lt;p&gt;This example illustrates one of the last key motivating point for me in Toucan. Everything is open, there’s room for everyone, every possible idea. Try, experiment, take feedback, adjust and your idea will spread over the company!&lt;/p&gt; 
&lt;h2&gt;We’re waiting for you&lt;/h2&gt; 
&lt;p&gt;Everything is not perfect and I did not expect something else. Besides the technical stack and the nice product, I mostly chose Tocan because of the nice human interactions I’ve had during the recruitment process and because I felt I would be given the opportunity to act on the organisation. 3 months later, I’m in, doing exactly that. The company moves fast, people are skilled and diverse but aligned on our core values. Our offices are great, it’s fun, why don’t you come and join us?&lt;/p&gt;</description>
      <content:encoded>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://www.toucantoco.com/en/tech-blog/3months-at-toucan" title="" class="hs-featured-image-link"&gt; &lt;img src="https://www.toucantoco.com/hubfs/Imported_Blog_Media/values-baloo-necessities-2.webp" alt="Why I chose Toucan Toco after 15 years in another company" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The aim of this article is to explain why I decided to apply for Toucan Toco&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;During the last few days, I’ve been asked a bunch of times by my workmates how I was feeling about my work @Toucan. I thought that it was time to take a few minutes to answer here and share some information with the outside world (or just with my last-year-self).&lt;/p&gt; 
&lt;h2&gt;Why did I choose ToucanToco ?&lt;/h2&gt; 
&lt;p&gt;I learned about Toucan Toco during some casual talks at &lt;a href="http://www.openvisconf.com/"&gt;OpenVis&lt;/a&gt;. A few weeks later, after having read the company’s blog posts and checked the product, I was impressed by the fact that the company grew that fast — 70 persons after 4 years — while being self-financed. The product seemed beautiful and easy to use, the technical stack (python / pandas / vuejs / d3js / ansible) was familiar yet motivating.&lt;/p&gt; 
&lt;p&gt;Besides the technical points, I also got the feeling that human factors, organisations and structural questions (agility, holacracy, core values, inclusion) were first-class citizens and this was a big motivator for me so I decided to apply.&lt;/p&gt; 
&lt;h2&gt;Onboarding&lt;/h2&gt; 
&lt;p&gt;I stayed more than 15 years — and it was a nice and rich experience! — in my previous company, so I was a bit skeptical about how long it would take me to get familiar with the code, product and internal processes. But no worries, Toucan has your back and you’ll be up and running very quickly!&lt;/p&gt; 
&lt;p&gt;Whether you are a developer, a sales person or a client success manager, chances are that you’ll have to get accustomed to your new &lt;a href="https://blog.trello.com/how-toucan-toco-used-trello-to-collaborate-with-ubisoft"&gt;Trello&lt;/a&gt; friend. We use it daily to organize and synchronize personal and team work. More specifically, Toucan Toco has crafted specific “onboarding boards” for each job. Each board defines a set of cards that should be completed during the first 2 months. These tasks range from very basic tasks such as “configure your slack profile” to specific development tasks such as “make a pull request on the product documentation” and more general ones such as “take part to a sales meeting”. These tasks are themselves organized week by week and provide a soft canvas that follows naturally your progression in the company. During all the process, another employee will mentor and will meet you at least once a week to provide feedback and help you finding your path in this welcoming, yet sometimes overwhelming environment.&lt;/p&gt; 
&lt;p&gt;From my point of view, it was a nice experience that helped me to quickly grasp the various tools, processes and cultural specificities of the company. I’ve heard a few of my colleagues say that it might be too heavy of a process. I concede that the number of trello cards is a bit frightening &lt;em&gt;but&lt;/em&gt; I do think it’s a very efficient way to ramp up and incite you to communicate with other teams (developers and sales talk together!) in a very comfy frame. For instance, during the first week — which passes through very quickly considering all the administrative tasks to perform, your laptop and tools to configure, etc. — I think I had already submitted a pull request on the product and reviewed a few which means that some of my code was in production on week 2, not so bad, huh? And I definitely attribute this “performance” to the onboarding process rather than to my personal skills.&lt;/p&gt;  
&lt;p&gt;Another achievement is that even if I’m definitely not fluent technically on all topics, I do think I would now be able to mentor a newcomer after only 3 months here.&lt;/p&gt; 
&lt;h2&gt;5 core values&lt;/h2&gt; 
&lt;p&gt;The onboarding process was also definitely a way to test how the &lt;a href="https://toucantoco.com/en/team.html#values"&gt;5 core values&lt;/a&gt; are spread through the company. &lt;em&gt;WTFM&lt;/em&gt; is clearly not an empty word: there is &lt;em&gt;a lot&lt;/em&gt; of documentation (technical, organisational, logbooks…). Of course the downside is to keep this documentation up-to-date but it’s a continuous and common effort and the onboarding period is clearly a good one to check if documentation matches reality (&lt;em&gt;spoiler&lt;/em&gt;: no… but everyone is encouraged to fix it!). One of the other core value &lt;em&gt;Be well and take care&lt;/em&gt; would be my personal favorite: 75 individuals, a lot of small teams, sometimes very solid, different perspectives, affinity, but despite this variety, I have the feeling that everyone tries hard to be benevolent and keep an inclusive mindset towards others, especially newcomers.&lt;/p&gt; 
&lt;p&gt;The recruitment process was also in retrospect a nice expression of Toucan Toco’s values. I felt sincere benevolence and care during the (admittedly a bit long) list of interviews. A candidate recently even thanked Toucan Toco on twitter despite its application dismissal. My technical skill test was 2-folded. First, I had to talk about a piece of software I had written (design or technical choices). I then took part to a “Technical enhancement Proposal” meeting, (e.g. &lt;a href="https://www.python.org/dev/peps/"&gt;PEP-like&lt;/a&gt; meeting for internal technical subjects). All ideas were listened to, each participant in the discussion — hopefully including me — had the chance to bring up relevant inputs (&lt;em&gt;Each one teach one&lt;/em&gt;, the 2nd core-value, Bingo!).&lt;/p&gt; 
&lt;p&gt;Core values are often emphasized on companies’ websites but they often sound shallow. After three months here, I’m happy to say that those core values are not a set of buzzwords. They’re regulary challenged and have even changed — the curious will dig the web — to better match the actual state of mind of the company.&lt;/p&gt; 
&lt;h2&gt;Constant feedback&lt;/h2&gt; 
&lt;p&gt;Continuing along with &lt;em&gt;Each one teach one&lt;/em&gt; at Toucan, the cultural fit is also spread through a few ceremonies. Besides the traditional weekly team retrospectives, there are 2 monthly events:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; &lt;p&gt;the “monthly news meeting”: each team in the company explains last month’s successes, failures and its updated roadmap. In my brief experience here, it’s a key event to share the global vision across all the company. This event is always a good place to keep everyone sync’ed and to deeply reinstate how each team’s objectives converge towards the same goal. It can be a very good motivator (often followed by a casual drink, which is always nice, just saying…),&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;the “product showcase”: the dev teams share with all other teams, during an hour, what was developed and shipped in the past month. We’re a “product-driven” company and this is where developers have a chance to shine. Each other team must leave that meeting confident that we’re making steady progress. We must share our vision, prove we’ve taken their feedback and keep on innovating.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;Aligned autonomy and room for improvement&lt;/h2&gt; 
&lt;p&gt;During my short time here, I was under the impression that our retrospectives did not capture enough some aspects of “human / organizational” topics. I thus proposed &lt;a href="https://labs.spotify.com/2014/09/16/squad-health-check-model/"&gt;specific workshops&lt;/a&gt; in the back-end team. It seemed convincing enough for the “front-end” team to try it. Now, the “project delivery” team will itself try it in a few days. I even had someone at the sales team asking me for more information about the workshop.&lt;/p&gt; 
&lt;p&gt;This example illustrates one of the last key motivating point for me in Toucan. Everything is open, there’s room for everyone, every possible idea. Try, experiment, take feedback, adjust and your idea will spread over the company!&lt;/p&gt; 
&lt;h2&gt;We’re waiting for you&lt;/h2&gt; 
&lt;p&gt;Everything is not perfect and I did not expect something else. Besides the technical stack and the nice product, I mostly chose Tocan because of the nice human interactions I’ve had during the recruitment process and because I felt I would be given the opportunity to act on the organisation. 3 months later, I’m in, doing exactly that. The company moves fast, people are skilled and diverse but aligned on our core values. Our offices are great, it’s fun, why don’t you come and join us?&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=8414155&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fwww.toucantoco.com%2Fen%2Ftech-blog%2F3months-at-toucan&amp;amp;bu=https%253A%252F%252Fwww.toucantoco.com%252Fen%252Ftech-blog&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <pubDate>Fri, 22 Feb 2019 05:00:00 GMT</pubDate>
      <guid>https://www.toucantoco.com/en/tech-blog/3months-at-toucan</guid>
      <dc:date>2019-02-22T05:00:00Z</dc:date>
      <dc:creator>Toucan Toco</dc:creator>
    </item>
  </channel>
</rss>
