<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jim Stoik</title>
    <description>The latest articles on DEV Community by Jim Stoik (@st0ik).</description>
    <link>https://dev.to/st0ik</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F8589%2F8d5a4e38-4d02-4942-b3ca-d70f49960de3.png</url>
      <title>DEV Community: Jim Stoik</title>
      <link>https://dev.to/st0ik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/st0ik"/>
    <language>en</language>
    <item>
      <title>The Last Thing You Should Read Before a Full-Stack Interview</title>
      <dc:creator>Jim Stoik</dc:creator>
      <pubDate>Fri, 06 Mar 2026 10:30:29 +0000</pubDate>
      <link>https://dev.to/st0ik/the-last-thing-you-should-read-before-a-full-stack-interview-21a3</link>
      <guid>https://dev.to/st0ik/the-last-thing-you-should-read-before-a-full-stack-interview-21a3</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I condensed years of Staff Engineering interview experience into a 30-minute "panic button" guide. &lt;strong&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide?_gl=1*1ipa21f*_ga*MTM3NjYxNDk2My4xNzY5MDc5MTA2*_ga_6LJN6D94N6*czE3NjkwNzkxMDYkbzEkZzEkdDE3NjkwODMyMDgkajYwJGwwJGgw" rel="noopener noreferrer"&gt;Grab the Fullstack Interview Pocket Guide here.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You know the moment.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;45 minutes before the interview&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your laptop is open.&lt;br&gt;&lt;br&gt;
Your coffee is getting cold.&lt;br&gt;&lt;br&gt;
Your brain suddenly decides to forget &lt;strong&gt;every concept you’ve learned in the last 10 years&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Questions start spinning in your head:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait… how exactly do I explain the Event Loop again?&lt;/li&gt;
&lt;li&gt;What’s the clean way to describe closures?&lt;/li&gt;
&lt;li&gt;Why do I always over-explain &lt;code&gt;useMemo&lt;/code&gt; and confuse myself?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ve built production systems.&lt;/p&gt;

&lt;p&gt;You’ve fixed outages.&lt;br&gt;&lt;br&gt;
You’ve reviewed pull requests for years.&lt;br&gt;&lt;br&gt;
You’ve shipped real software used by real users.&lt;/p&gt;

&lt;p&gt;But interviews do something strange to engineers.&lt;/p&gt;

&lt;p&gt;They &lt;strong&gt;scramble your thoughts&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real reason good engineers fail interviews
&lt;/h2&gt;

&lt;p&gt;Most engineers don’t fail interviews because they lack knowledge.&lt;/p&gt;

&lt;p&gt;They fail because they &lt;strong&gt;can’t articulate what they already know under pressure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Technical interviews are not really knowledge tests.&lt;/p&gt;

&lt;p&gt;They are &lt;strong&gt;communication tests disguised as technical tests&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Strong candidates don’t just know things.&lt;/p&gt;

&lt;p&gt;They explain them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clearly
&lt;/li&gt;
&lt;li&gt;calmly
&lt;/li&gt;
&lt;li&gt;with structure
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s the difference between someone who &lt;em&gt;knows JavaScript&lt;/em&gt; and someone who &lt;strong&gt;sounds like a senior engineer&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem with most interview prep
&lt;/h2&gt;

&lt;p&gt;Most interview prep material looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;300 page books
&lt;/li&gt;
&lt;li&gt;endless video courses
&lt;/li&gt;
&lt;li&gt;deep academic explanations
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But right before an interview you don’t need &lt;strong&gt;more information&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You need &lt;strong&gt;clarity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You need something that helps you quickly remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how to structure answers&lt;/li&gt;
&lt;li&gt;how to explain concepts&lt;/li&gt;
&lt;li&gt;how to think out loud like an experienced engineer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Something you can read &lt;strong&gt;before the interview starts&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Full-Stack Interview Pocket Guide
&lt;/h2&gt;

&lt;p&gt;So I created something I always wished I had before interviews.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Full-Stack Engineer Interview Pocket Guide&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can check it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide" rel="noopener noreferrer"&gt;https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;not a course&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s the &lt;strong&gt;last thing you read before an interview&lt;/strong&gt; to reset your brain.&lt;/p&gt;

&lt;p&gt;Think of it as a &lt;strong&gt;mental warm-up for engineers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Athletes warm up before a match.&lt;/p&gt;

&lt;p&gt;Musicians tune their instruments before performing.&lt;/p&gt;

&lt;p&gt;This guide does the same thing for your &lt;strong&gt;technical thinking&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What makes this guide different
&lt;/h2&gt;

&lt;p&gt;Most interview prep teaches:&lt;/p&gt;

&lt;p&gt;“What things are.”&lt;/p&gt;

&lt;p&gt;This guide focuses on something much more practical:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How senior engineers explain them during interviews.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every topic follows the same simple structure.&lt;/p&gt;

&lt;p&gt;First: a &lt;strong&gt;one-liner&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The kind of answer that immediately shows confidence.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;“A closure is when a function retains access to variables from its lexical scope even after the outer function has finished executing.”&lt;/p&gt;

&lt;p&gt;Short. Clear. Direct.&lt;/p&gt;

&lt;p&gt;Then comes a &lt;strong&gt;clean explanation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Something structured that you can say calmly without rambling.&lt;/p&gt;

&lt;p&gt;After that, the guide explains &lt;strong&gt;why interviewers ask the question&lt;/strong&gt; in the first place.&lt;/p&gt;

&lt;p&gt;Because most questions are not about trivia.&lt;/p&gt;

&lt;p&gt;They’re about whether you understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;debugging&lt;/li&gt;
&lt;li&gt;performance&lt;/li&gt;
&lt;li&gt;scalability&lt;/li&gt;
&lt;li&gt;real engineering trade-offs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, it covers &lt;strong&gt;common follow-ups&lt;/strong&gt; and &lt;strong&gt;real world trade-offs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not theoretical definitions.&lt;/p&gt;

&lt;p&gt;The kind of thinking experienced engineers use in real systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s inside
&lt;/h2&gt;

&lt;p&gt;The guide compresses a lot of common interview topics into a quick refresh format.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript
&lt;/h3&gt;

&lt;p&gt;The concepts that appear in interviews again and again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;closures&lt;/li&gt;
&lt;li&gt;the event loop&lt;/li&gt;
&lt;li&gt;promises vs async/await&lt;/li&gt;
&lt;li&gt;microtasks vs macrotasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;this&lt;/code&gt; binding&lt;/li&gt;
&lt;li&gt;immutability&lt;/li&gt;
&lt;li&gt;prototypes&lt;/li&gt;
&lt;li&gt;async anti-patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;The things that separate mid engineers from senior ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;any&lt;/code&gt; vs &lt;code&gt;unknown&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;generics&lt;/li&gt;
&lt;li&gt;utility types&lt;/li&gt;
&lt;li&gt;discriminated unions&lt;/li&gt;
&lt;li&gt;mapped types&lt;/li&gt;
&lt;li&gt;&lt;code&gt;as const&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;React + TypeScript patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Node.js &amp;amp; backend fundamentals
&lt;/h3&gt;

&lt;p&gt;Topics backend interviews love:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the Node event loop&lt;/li&gt;
&lt;li&gt;libuv basics&lt;/li&gt;
&lt;li&gt;streams and backpressure&lt;/li&gt;
&lt;li&gt;worker threads&lt;/li&gt;
&lt;li&gt;clustering&lt;/li&gt;
&lt;li&gt;JWT vs sessions&lt;/li&gt;
&lt;li&gt;debugging production crashes&lt;/li&gt;
&lt;li&gt;security thinking&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  React architecture
&lt;/h3&gt;

&lt;p&gt;Common frontend interview discussions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the virtual DOM&lt;/li&gt;
&lt;li&gt;reconciliation&lt;/li&gt;
&lt;li&gt;hooks internals&lt;/li&gt;
&lt;li&gt;performance optimisation&lt;/li&gt;
&lt;li&gt;memoization trade-offs&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;SSR vs CSR vs SSG&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Databases &amp;amp; system design
&lt;/h3&gt;

&lt;p&gt;Simple explanations for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data modelling&lt;/li&gt;
&lt;li&gt;SQL vs NoSQL decisions&lt;/li&gt;
&lt;li&gt;scalability thinking&lt;/li&gt;
&lt;li&gt;architecture trade-offs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SOLID and design patterns
&lt;/h3&gt;

&lt;p&gt;Not academic definitions.&lt;/p&gt;

&lt;p&gt;Just how they &lt;strong&gt;actually appear in real codebases&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behavioural interviews
&lt;/h3&gt;

&lt;p&gt;Because interviews are also about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;communication&lt;/li&gt;
&lt;li&gt;ownership&lt;/li&gt;
&lt;li&gt;decision making&lt;/li&gt;
&lt;li&gt;explaining trade-offs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;This isn’t meant to be a long study resource.&lt;/p&gt;

&lt;p&gt;It’s designed to be used like this.&lt;/p&gt;

&lt;p&gt;Full read: about &lt;strong&gt;90 minutes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quick refresh: &lt;strong&gt;30–45 minutes before an interview&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;p&gt;skim what you already know and focus on areas where your explanations feel weak.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this works
&lt;/h2&gt;

&lt;p&gt;Interviewers are not looking for people who memorise documentation.&lt;/p&gt;

&lt;p&gt;They look for engineers who can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explain ideas clearly
&lt;/li&gt;
&lt;li&gt;reason about trade-offs
&lt;/li&gt;
&lt;li&gt;stay calm under pressure
&lt;/li&gt;
&lt;li&gt;think like owners
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, people who &lt;strong&gt;sound like someone they want to work with&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you have an interview coming up
&lt;/h2&gt;

&lt;p&gt;Keep the guide somewhere easy to access.&lt;/p&gt;

&lt;p&gt;Read it before the interview.&lt;/p&gt;

&lt;p&gt;Reset your thinking.&lt;/p&gt;

&lt;p&gt;Walk in calm.&lt;/p&gt;

&lt;p&gt;You can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide" rel="noopener noreferrer"&gt;https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Most engineers already know the material.&lt;/p&gt;

&lt;p&gt;They’ve written the code.&lt;br&gt;&lt;br&gt;
They’ve debugged the systems.&lt;br&gt;&lt;br&gt;
They’ve solved the problems.&lt;/p&gt;

&lt;p&gt;Sometimes they just need &lt;strong&gt;a structured reset before the interview begins&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s what this guide is for.&lt;/p&gt;

&lt;p&gt;If you're curious, take a look here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide" rel="noopener noreferrer"&gt;https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you’ve done a lot of interviews, I’m curious:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what question shows up almost every single time?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>interview</category>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>Interview in an Hour? Read This Fullstack Pocket Guide.</title>
      <dc:creator>Jim Stoik</dc:creator>
      <pubDate>Thu, 22 Jan 2026 12:13:18 +0000</pubDate>
      <link>https://dev.to/st0ik/interview-in-an-hour-read-this-fullstack-pocket-guide-45j6</link>
      <guid>https://dev.to/st0ik/interview-in-an-hour-read-this-fullstack-pocket-guide-45j6</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I condensed years of Staff Engineering interview experience into a 30-minute "panic button" guide. &lt;strong&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide?_gl=1*1ipa21f*_ga*MTM3NjYxNDk2My4xNzY5MDc5MTA2*_ga_6LJN6D94N6*czE3NjkwNzkxMDYkbzEkZzEkdDE3NjkwODMyMDgkajYwJGwwJGgw" rel="noopener noreferrer"&gt;Grab the Fullstack Interview Pocket Guide here.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;You know that feeling.&lt;/p&gt;

&lt;p&gt;It’s 45 minutes before &lt;em&gt;The Big Interview&lt;/em&gt;. You’re sitting in your car (or staring at a blank VS Code window), and suddenly, your brain decides to dump every piece of technical knowledge you own.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;"Wait, what exactly is the difference between &lt;code&gt;useMemo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt; again?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;"Can I explain the Node.js Event Loop without sounding like I'm guessing?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;"What does the 'L' in SOLID stand for?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't have time to read "Cracking the Coding Interview" cover-to-cover. You don't have time to watch a 4-hour Udemy course.&lt;/p&gt;

&lt;p&gt;You need a &lt;strong&gt;refresh&lt;/strong&gt;. You need high-signal, low-noise answers.&lt;/p&gt;

&lt;p&gt;I wrote the &lt;strong&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide?_gl=1*1ipa21f*_ga*MTM3NjYxNDk2My4xNzY5MDc5MTA2*_ga_6LJN6D94N6*czE3NjkwNzkxMDYkbzEkZzEkdDE3NjkwODMyMDgkajYwJGwwJGgw" rel="noopener noreferrer"&gt;Fullstack Engineer Interview Pocket Guide&lt;/a&gt;&lt;/strong&gt; for exactly this moment. It is designed to be consumed in &lt;strong&gt;30 to 60 minutes&lt;/strong&gt;. It cuts the fluff and gives you the "Staff Engineer" answers, pragmatic, concise, and technically accurate.&lt;/p&gt;

&lt;p&gt;Here is a sneak peek of what’s inside.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡️ The 5-Minute Refresher (Samples from the Book)
&lt;/h3&gt;

&lt;p&gt;Here is how we condense complex topics into interview-ready nuggets.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. JavaScript: The Event Loop (Simplified)
&lt;/h4&gt;

&lt;p&gt;Don't get lost in the weeds. Explain it like this:&lt;br&gt;
JavaScript is single-threaded. It uses the &lt;strong&gt;Call Stack&lt;/strong&gt; to run code, the &lt;strong&gt;Web APIs&lt;/strong&gt; (like &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;fetch&lt;/code&gt;) to handle async tasks, and the &lt;strong&gt;Callback Queue&lt;/strong&gt; to hold finished tasks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Golden Rule:&lt;/strong&gt; The Event Loop simply checks: &lt;em&gt;"Is the Call Stack empty?"&lt;/em&gt; If yes, it pushes the first item from the Queue to the Stack.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Microtasks (Promises)&lt;/strong&gt; have priority over Macrotasks (setTimeout).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. React: &lt;code&gt;useMemo&lt;/code&gt; vs &lt;code&gt;useCallback&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Stop mixing them up. It comes down to &lt;strong&gt;Value&lt;/strong&gt; vs. &lt;strong&gt;Function&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;useMemo&lt;/code&gt;:&lt;/strong&gt; Caches the &lt;strong&gt;result&lt;/strong&gt; of a calculation. Use it when the calculation is expensive (looping millions of items).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;useCallback&lt;/code&gt;:&lt;/strong&gt; Caches the &lt;strong&gt;function definition&lt;/strong&gt; itself. Use it to prevent a child component from re-rendering just because a function prop "changed" (reference equality).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Database: ACID Properties
&lt;/h4&gt;

&lt;p&gt;If they ask about transactions, just remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;A (Atomicity):&lt;/strong&gt; All or nothing. If one part fails, the whole transaction rolls back.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;C (Consistency):&lt;/strong&gt; The DB moves from one valid state to another (constraints are respected).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;I (Isolation):&lt;/strong&gt; Concurrent transactions don't mess with each other.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;D (Durability):&lt;/strong&gt; Once saved, it stays saved. Even if the power goes out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. Node.js: The "Single Thread" Myth
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Interviewer: "Is Node.js strictly single-threaded?"&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Your Answer:&lt;/strong&gt; "The Event Loop is single-threaded, which makes Node great for I/O-heavy tasks. However, Node uses &lt;code&gt;libuv&lt;/code&gt; to offload heavy operations (like file I/O, crypto, or compression) to a pool of worker threads at the C++ level. So, it's single-threaded orchestration, multi-threaded execution."&lt;/p&gt;

&lt;h4&gt;
  
  
  5. SOLID Principles: The Liskov Substitution Principle (LSP)
&lt;/h4&gt;

&lt;p&gt;The hardest one to explain simply.&lt;br&gt;
&lt;strong&gt;The Gist:&lt;/strong&gt; Subclasses should be substitutable for their base classes.&lt;br&gt;
&lt;strong&gt;The "Duck" Test:&lt;/strong&gt; If it looks like a duck and quacks like a duck but requires batteries, you have the wrong abstraction. If you override a parent method but throw an error because "this subclass doesn't support that method," you violated LSP.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 Behavioral: The STAR Method
&lt;/h3&gt;

&lt;p&gt;Technical skills get you the interview; soft skills get you the job. When asked &lt;em&gt;"Tell me about a time you failed,"&lt;/em&gt; use the &lt;strong&gt;STAR&lt;/strong&gt; pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;S&lt;/strong&gt;ituation (The context)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;T&lt;/strong&gt;ask (The goal)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;A&lt;/strong&gt;ction (What &lt;em&gt;you&lt;/em&gt; specifically did)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;R&lt;/strong&gt;esult (The outcome, preferably with numbers)&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Why I wrote this guide
&lt;/h3&gt;

&lt;p&gt;I am a Staff Software Engineer who has conducted hundreds of interviews. I realised that most candidates know the code, but they  struggle to &lt;strong&gt;communicate the concepts&lt;/strong&gt; clearly under pressure.&lt;/p&gt;

&lt;p&gt;I didn't want to write another 400-page textbook. I wanted to create the "Cheat Sheet" I wish I had before every interview.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Guide Covers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ✅ Modern JavaScript (ES6+) &amp;amp; TypeScript&lt;/li&gt;
&lt;li&gt;  ✅ Node.js Internals&lt;/li&gt;
&lt;li&gt;  ✅ React Patterns &amp;amp; Hooks&lt;/li&gt;
&lt;li&gt;  ✅ Databases (SQL vs NoSQL)&lt;/li&gt;
&lt;li&gt;  ✅ Design Patterns &amp;amp; SOLID&lt;/li&gt;
&lt;li&gt;  ✅ Behavioral Questions &amp;amp; "Red Flags" to avoid&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚀 Get the Edge
&lt;/h3&gt;

&lt;p&gt;Don't let a mental block cost you the offer. Keep this guide on your phone or Kindle. Read it while you wait. Walk into the interview with the confidence of a senior engineer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://jimstoik.gumroad.com/l/Full-Stack-Engineer-Interview-pocket-guide?_gl=1*1ipa21f*_ga*MTM3NjYxNDk2My4xNzY5MDc5MTA2*_ga_6LJN6D94N6*czE3NjkwNzkxMDYkbzEkZzEkdDE3NjkwODMyMDgkajYwJGwwJGgw" rel="noopener noreferrer"&gt;👉 Download the Fullstack Engineer Interview Pocket Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good luck. You've got this.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>career</category>
      <category>interview</category>
    </item>
    <item>
      <title>Introduction to Jest: Unit Testing, Mocking, and Asynchronous Code</title>
      <dc:creator>Jim Stoik</dc:creator>
      <pubDate>Wed, 30 Oct 2024 22:59:11 +0000</pubDate>
      <link>https://dev.to/st0ik/introduction-to-jest-unit-testing-mocking-and-asynchronous-code-485a</link>
      <guid>https://dev.to/st0ik/introduction-to-jest-unit-testing-mocking-and-asynchronous-code-485a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Jest
&lt;/h2&gt;

&lt;p&gt;Jest is a library for testing JavaScript code.&lt;/p&gt;

&lt;p&gt;It’s an open source project maintained by Facebook, and it’s especially well suited for React code testing, although not limited to that: it can test any JavaScript code. Its strengths are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it’s fast&lt;/li&gt;
&lt;li&gt;it can perform snapshot testing&lt;/li&gt;
&lt;li&gt;it’s opinionated, and provides everything out of the box without requiring you to make choices
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;p&gt;&lt;strong&gt;divide.test.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sum&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;./sum&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Describe the test and wrap it in a function.&lt;/span&gt;
&lt;span class="nf"&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;adds 1 + 2 to equal 3&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Jest uses matchers, like pretty much any other JavaScript testing framework.&lt;/span&gt;
  &lt;span class="c1"&gt;// They're designed to be easy to get at a glance;&lt;/span&gt;
  &lt;span class="c1"&gt;// here, you're expecting `result` to be 3.&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Matchers
&lt;/h2&gt;

&lt;p&gt;A matcher is a method that lets you test values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;toBe&lt;/code&gt; compares strict equality, using &lt;code&gt;===&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toEqual&lt;/code&gt; compares the values of two variables. If it’s an object or array, it checks the equality of all the properties or elements&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeNull&lt;/code&gt; is true when passing a null value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeDefined&lt;/code&gt; is true when passing a defined value (opposite to the above)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeUndefined&lt;/code&gt; is true when passing an undefined value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeCloseTo&lt;/code&gt; is used to compare floating values, avoiding rounding errors&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeTruthy&lt;/code&gt; true if the value is considered true (like an if does)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeFalsy&lt;/code&gt; true if the value is considered false (like an if does)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeGreaterThan&lt;/code&gt; true if the result of expect() is higher than the argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeGreaterThanOrEqual&lt;/code&gt; true if the result of expect() is equal to the argument, or higher than the argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeLessThan&lt;/code&gt; true if the result of expect() is lower than the argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeLessThanOrEqual&lt;/code&gt; true if the result of expect() is equal to the argument, or lower than the argument&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toMatch&lt;/code&gt; is used to compare strings with regular expression pattern matching&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toContain&lt;/code&gt; is used in arrays, true if the expected array contains the argument in its elements set&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toHaveLength(number)&lt;/code&gt;: checks the length of an array&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toHaveProperty(key, value)&lt;/code&gt;: checks if an object has a property, and optionally checks its value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toThrow&lt;/code&gt; checks if a function you pass throws an exception (in general) or a specific exception&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toBeInstanceOf()&lt;/code&gt;: checks if an object is an instance of a class&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dependencies
&lt;/h2&gt;

&lt;p&gt;A dependency is a piece of code that your application depends on. It could be a function/Object in our project or a third-party dependency (ex axios)&lt;/p&gt;

&lt;p&gt;A piece of code becomes a true dependency when your own application cannot function without it. &lt;/p&gt;

&lt;p&gt;For example, if you implement a feature in your application to send email or make api requests or build a configuration object etc&lt;/p&gt;

&lt;p&gt;There are &lt;strong&gt;two ways&lt;/strong&gt; that we can add dependencies in our code in a js project:&lt;/p&gt;

&lt;h3&gt;
  
  
  Imports
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reportArea&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reportPerimeter&lt;/span&gt; &lt;span class="p"&gt;}&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;./modules/square.js&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;h3&gt;
  
  
  Dependency Injection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Just a fancy term on a simple concept.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your function needs some functionality from an external dependency, just inject it as an argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Constructor Injection&lt;/span&gt;

&lt;span class="c1"&gt;// DatabaseManager class takes a database connector as a dependency&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;databaseConnector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Dependency injection of the database connector&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;databaseConnector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;databaseConnector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;updateRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowId&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="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Use the injected database connector to perform the update&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;databaseConnector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowId&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// parameter injection, takes a database connector instance in as an argument; easy to test!&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowId&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="nx"&gt;databaseConnector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;databaseConnector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowId&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="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Unit Testing
&lt;/h2&gt;

&lt;p&gt;Unit tests are written and run by software developers to ensure that a section of an application (known as the "unit") meets its design and behaves as intended.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We want to test our code in isolation, we don't care about the actual implementation of any dependencies.&lt;/strong&gt;&lt;br&gt;
We want to verify &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;that our unit of code works as expected&lt;/li&gt;
&lt;li&gt;returns the expected results &lt;/li&gt;
&lt;li&gt;calls any collaborators(dependencies) as it should&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is where mocking our dependencies comes into play.&lt;/p&gt;
&lt;h2&gt;
  
  
  Mocking
&lt;/h2&gt;

&lt;p&gt;In unit testing, mocks provide us with the &lt;strong&gt;capability to stub the functionality provided by a dependency&lt;/strong&gt; and a &lt;strong&gt;means to observe how our code interacts with the dependency&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Mocks are especially useful when it's expensive or impractical to include a dependency directly into our tests, for example, in cases where your code is &lt;em&gt;making HTTP calls to an API or interacting with the database layer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It is preferable to stub out the responses for these dependencies, while making sure that they are called as required. This is where mocks come in handy.&lt;/p&gt;

&lt;p&gt;By using mock functions, we can know the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;number of calls&lt;/strong&gt; it received.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argument&lt;/strong&gt; values used on each invocation.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;“context” or this&lt;/strong&gt; value on each invocation.&lt;/li&gt;
&lt;li&gt;How the function exited and &lt;strong&gt;what values were produced&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Mocking in Jest
&lt;/h2&gt;

&lt;p&gt;There are several ways to create mock functions. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;jest.fn&lt;/code&gt; method allows us to create a new mock function directly. &lt;/li&gt;
&lt;li&gt;If you are mocking an object method, you can use &lt;code&gt;jest.spyOn&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;And if you want to mock a whole module, you can use &lt;code&gt;jest.mock&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;jest.fn&lt;/code&gt; method is, by itself, a &lt;code&gt;higher-order function&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's a factory method that creates new, unused mock functions.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Functions in JavaScript are first-class citizens, they can be passed around as arguments. &lt;/p&gt;

&lt;p&gt;Each mock function has some special properties. The mock property is fundamental. This property is an object that has all the mock state information about how the function was invoked. This object contains three array properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calls&lt;/strong&gt; [arguments of each call]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instances&lt;/strong&gt; ['this' value on each call]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Results&lt;/strong&gt; [the value that the function exited], the &lt;code&gt;results&lt;/code&gt; property has &lt;code&gt;type&lt;/code&gt;(return or throw) and &lt;code&gt;value&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;The function explicitly returns a value.&lt;/li&gt;
&lt;li&gt;The function runs to completion with no return statement (which is equivalent to returning undefined&lt;/li&gt;
&lt;li&gt;The function throws an error.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. The mock function factory&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;impl&lt;/span&gt; &lt;span class="o"&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="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 2. The mock function&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockFn&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;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 4. Store the arguments used&lt;/span&gt;
    &lt;span class="nx"&gt;mockFn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;mockFn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="k"&gt;try&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;impl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&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;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// call impl, passing the right this&lt;/span&gt;
      &lt;span class="nx"&gt;mockFn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// return the value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;mockFn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;throw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// re-throw the error&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// 3. Mock state&lt;/span&gt;
  &lt;span class="nx"&gt;mockFn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="na"&gt;results&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;return&lt;/span&gt; &lt;span class="nx"&gt;mockFn&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;ul&gt;
&lt;li&gt;&lt;a href="https://codesandbox.io/s/implementing-mock-functions-tkc8b" rel="noopener noreferrer"&gt;https://codesandbox.io/s/implementing-mock-functions-tkc8b&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Mock Basic
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;returns undefined by 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="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;mock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeUndefined&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&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;h3&gt;
  
  
  Mocking injected dependencies
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doAdd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calls callback with arguments added&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;doAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mockCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockCallback&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Mocking modules
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Mock a function with &lt;code&gt;jest.fn&lt;/code&gt;
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;app&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;math&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./math&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calls math.add&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calls math.subtract&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doSubtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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;p&gt;This type of mocking is less common for a couple reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jest.mock&lt;/code&gt; does this automatically for all functions in a module&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jest.spyOn&lt;/code&gt; does the same thing but allows restoring the original function&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Mock a module with jest.mock
&lt;/h4&gt;

&lt;p&gt;A more common approach is to use &lt;code&gt;jest.mock&lt;/code&gt; &lt;strong&gt;to automatically set all exports of a module to the Mock Function&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;app&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;math&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./math&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Set all module functions to jest.fn&lt;/span&gt;
&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./math.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calls math.add&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calls math.subtract&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doSubtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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;h4&gt;
  
  
  Spy or mock a function with jest.spyOn
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Sometimes you only want to watch a method be called, but keep the original implementation&lt;/strong&gt;. Other times you may want to mock the implementation, but restore the original later in the suite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;app&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;math&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./math&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calls math.add&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// calls the original implementation&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;doAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// and the spy stores the calls to add&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addMock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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;p&gt;Restore the original implementation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// restore the original implementation
  addMock.mockRestore();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Javascript and the Event Loop
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JavaScript is single-threaded:&lt;/strong&gt; only one task can run at a time. Usually that’s no big deal, but now imagine you’re running a task which takes 30 seconds.. Ya.. During that task we’re waiting for 30 seconds before anything else can happen (JavaScript runs on the browser’s main thread by default, so the entire UI is stuck).&lt;br&gt;
It’s 2020, no one wants a slow, unresponsive website.&lt;/p&gt;

&lt;p&gt;Luckily, the browser gives us some features that the JavaScript engine itself doesn’t provide: &lt;strong&gt;a Web API&lt;/strong&gt;. This includes the &lt;strong&gt;DOM API&lt;/strong&gt;, &lt;strong&gt;setTimeout&lt;/strong&gt;, &lt;strong&gt;HTTP requests&lt;/strong&gt;, and so on. This can help us create some &lt;strong&gt;async&lt;/strong&gt;, &lt;strong&gt;non-blocking behavior&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&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="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Call Stack&lt;/strong&gt; - When we invoke a function, it gets added to something called the call stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebAPI&lt;/strong&gt; - setTimeout is provided by the WebAPI, takes a callback function and sets up a timer without blocking the main thread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queue&lt;/strong&gt; - when the timer finishes, the callback gets added into the Queue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Loop&lt;/strong&gt; - checks if the call-stack is empty, checks if there are any callbacks to be executed in the Queue, and moves to the call stack to be executed
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First&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;bar&lt;/span&gt; &lt;span class="o"&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="nf"&gt;setTimeout&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Second&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baz&lt;/span&gt; &lt;span class="o"&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Third&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;h2&gt;
  
  
  Testing asynchronous code with Jest
&lt;/h2&gt;

&lt;p&gt;Jest typically expects to execute the tests’ functions &lt;strong&gt;synchronously&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If we do an asynchronous operation, but we don't let Jest know that it should wait for the test to end, it will give a false positive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this shouldn't pass&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&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;// this should fail:&lt;/span&gt;
    &lt;span class="nf"&gt;expect&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="nf"&gt;toBe&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;p&gt;&lt;strong&gt;Asynchronous Patterns&lt;/strong&gt;&lt;br&gt;
There are several patterns for handling async operations in JavaScript; the most used ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Callbacks&lt;/li&gt;
&lt;li&gt;Promises &amp;amp; Async/Await&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Testing Callbacks
&lt;/h3&gt;

&lt;p&gt;You can’t have a test in a callback, because Jest won’t execute it - the execution of the test file ends before the callback is called. To fix this, pass a parameter to the test function, which you can conveniently call &lt;code&gt;done&lt;/code&gt;. Jest will wait until you call &lt;code&gt;done()&lt;/code&gt; before ending that test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//uppercase.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;())&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="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uppercase&lt;/span&gt;

&lt;span class="c1"&gt;//uppercase.test.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uppercase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/uppercase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`uppercase 'test' to equal 'TEST'`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;done&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="nf"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&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;str&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TEST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;done&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;h4&gt;
  
  
  Promises
&lt;/h4&gt;

&lt;p&gt;With functions that return promises, we return a promise from the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//uppercase.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uppercase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Empty string&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uppercase&lt;/span&gt;

&lt;span class="c1"&gt;//uppercase.test.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uppercase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./uppercase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`uppercase 'test' to equal 'TEST'`&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TEST&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Async/await
&lt;/h4&gt;

&lt;p&gt;To test functions that return promises we can also use async/await, which makes the syntax very straightforward and simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//uppercase.test.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uppercase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./uppercase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`uppercase 'test' to equal 'TEST'`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TEST&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;h2&gt;
  
  
  Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We need to have a good understanding of what our function does and what we are about to test&lt;/li&gt;
&lt;li&gt;Think about the behaviour of the code that we are testing&lt;/li&gt;
&lt;li&gt;Set the stage:

&lt;ul&gt;
&lt;li&gt;Mock/Spy on any dependencies&lt;/li&gt;
&lt;li&gt;Is our code interacting with global objects? we can mock/spy on them too&lt;/li&gt;
&lt;li&gt;Are our tests interacting with the DOM? we can build some fake elements to work with&lt;/li&gt;
&lt;li&gt;Structure your tests&lt;/li&gt;
&lt;li&gt;Given ...&lt;/li&gt;
&lt;li&gt;When I call ....&lt;/li&gt;
&lt;li&gt;Then ... I expect.....
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&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;first set&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;beforeEach&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;//do something&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nf"&gt;afterAll&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;//do something&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*...*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*...*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&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;second set&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;beforeEach&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;//do something&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nf"&gt;beforeAll&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;//do something&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*...*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&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;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@rickhanlonii/understanding-jest-mocks-f0046c68e53c" rel="noopener noreferrer"&gt;https://medium.com/@rickhanlonii/understanding-jest-mocks-f0046c68e53c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/docs/en/mock-functions" rel="noopener noreferrer"&gt;https://jestjs.io/docs/en/mock-functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codesandbox.io/s/implementing-mock-functions-tkc8b" rel="noopener noreferrer"&gt;https://codesandbox.io/s/implementing-mock-functions-tkc8b&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/BulbEnergy/jest-mock-examples" rel="noopener noreferrer"&gt;https://github.com/BulbEnergy/jest-mock-examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif"&gt;https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/docs/en/asynchronous" rel="noopener noreferrer"&gt;https://jestjs.io/docs/en/asynchronous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pluralsight.com/guides/test-asynchronous-code-jest" rel="noopener noreferrer"&gt;https://www.pluralsight.com/guides/test-asynchronous-code-jest&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jest</category>
      <category>javascript</category>
      <category>unittesting</category>
      <category>mocking</category>
    </item>
    <item>
      <title>FizzBuzz Typescript &amp; SOLID Principles</title>
      <dc:creator>Jim Stoik</dc:creator>
      <pubDate>Sun, 24 May 2020 22:30:39 +0000</pubDate>
      <link>https://dev.to/st0ik/fizzbuzz-typescript-solid-principles-4e6f</link>
      <guid>https://dev.to/st0ik/fizzbuzz-typescript-solid-principles-4e6f</guid>
      <description>&lt;p&gt;&lt;strong&gt;"FizzBuzz"&lt;/strong&gt; is a well-known programming assignment, often used as a little test to see if a candidate for a programming job could manage to implement a set of requirements, usually on the spot. The requirements are these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Given a list of numbers from 1 to n.&lt;/li&gt;
&lt;li&gt;If a number is divisible by 3 should be replaced with Fizz.&lt;/li&gt;
&lt;li&gt;If a number is divisible by 5 should be replaced with Buzz.&lt;/li&gt;
&lt;li&gt;If a number is divisible by 3 and by 5 should be replaced with FizzBuzz.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applying these rules, the resulting list would become:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;1, 2, Fizz, 4, Buzz … 13, 14, FizzBuzz, 16, 17 …&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A simple solution often found online could be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for &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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&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="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FizzBuzz&lt;/span&gt;&lt;span class="dl"&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="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fizz&lt;/span&gt;&lt;span class="dl"&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="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Buzz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fizzBuzz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &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;p&gt;The Class above does the job. And solves the problem, BUT... what if we wanted to introduce a new rule? &lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;If a number is divisible by 7 should be replaced with Bazz.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FizzBuzz Class and the Open/Closed Principle
&lt;/h2&gt;

&lt;p&gt;If numbers divisible by 7 should one day be replaced with &lt;code&gt;Bazz&lt;/code&gt;, &lt;strong&gt;it will be impossible to implement this change without actually modifying the code of the FizzBuzz class.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Currently the FizzBuzz class is not open for extension, nor closed for modification.&lt;/strong&gt; Our current implementation violates the Open/Closed principle&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;Open/Closed Principle&lt;/strong&gt; says that the code should be open for extension but closed for modification. In other words, the code should be organized in such a way that new modules can be added without modifying the existing code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  FizzBuzz Class and the Singe Responsibility Principle
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have one, and only one, reason to change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our class has two responsibilities, therefore two reasons to change. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it generates a list of numbers and &lt;/li&gt;
&lt;li&gt;it generates replacement for each number based on the FizzBuzz Rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we think about it. Every responsibility that a class has... &lt;em&gt;is a reason to change&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-designing our Class
&lt;/h2&gt;

&lt;p&gt;How can we make our FizzBuzz class more Flexible? What is likely to change? &lt;/p&gt;

&lt;p&gt;The FizzBuzz rules are liable to change. And if we want to follow the &lt;strong&gt;Open/Closed principle&lt;/strong&gt;, we should not need to modify the &lt;code&gt;FizzBuzz Class&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;Lets try to think about the problem we are trying to solve here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We want  to generate a list of numbers, replacing certain numbers with strings, based on a flexible set of "rules".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lets start by introducing a &lt;code&gt;RuleInterface&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&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;p&gt;and lets extract the rules we need to solve the &lt;code&gt;FizzBuzz&lt;/code&gt; challenge into their own classes and have them implement the &lt;code&gt;RuleInterface&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzRule&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&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;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fizz&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BuzzRule&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&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;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Buzz&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzRule&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&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;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FizzBuzz&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, lets make our FizzBuzz Class &lt;strong&gt;Open For Extension&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We allow our class to get a list of rules, and build the replacements based on them. These rules must implement the &lt;code&gt;RuleInterface&lt;/code&gt; making our code flexible &amp;amp; extensible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&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;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="k"&gt;for &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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &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;rule&lt;/span&gt; &lt;span class="k"&gt;of&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;rules&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;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&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;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getReplacement&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;return&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fizBuzz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzRule&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzRule&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BuzzRule&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19, Buzz&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &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;h2&gt;
  
  
  FizzBuzz Class and the Dependency Inversion Principle
&lt;/h2&gt;

&lt;p&gt;The last of the &lt;strong&gt;SOLID principles&lt;/strong&gt; of class design focuses on class dependencies. It tells you what kinds of things a class should depend on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Depend on abstractions, not on concretions.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The principle tells we should always depend on abstractions(&lt;em&gt;Interfaces, Abstract Classes&lt;/em&gt;) and not on concrete implementations.&lt;/p&gt;

&lt;p&gt;Applying the Dependency Inversion principle in your code &lt;strong&gt;&lt;em&gt;will make it easy for users to swap out certain parts of your code with other parts that are tailored to their specific situation&lt;/em&gt;&lt;/strong&gt;. At the same time, your code remains general and abstract and therefore highly reusable.&lt;/p&gt;

&lt;p&gt;By introducing the &lt;code&gt;RuleInterface&lt;/code&gt; and adding specific rule classes that implemented this interface, the FizzBuzz class started to depend on more abstract things, called "rules".&lt;/p&gt;

&lt;p&gt;When creating a new &lt;code&gt;FizzBuzz&lt;/code&gt; instance, concrete implementations of &lt;code&gt;RuleInterface&lt;/code&gt; have to be injected in the right order. This will result in the correct execution of the FizzBuzz algorithm. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The FizzBuzz class itself is no longer concerned about the actual rules, which is why the class ends up being more flexible with regard to changing requirements.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Now the hardest part... Naming things!
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;/p&gt;

&lt;p&gt;-- Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we have a highly generic piece of code, which “&lt;strong&gt;generates a list of numbers, replacing certain numbers with strings, based on a flexible set of rules”&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;There is nothing &lt;strong&gt;FizzBuzz&lt;/strong&gt; specific about our class anymore!&lt;/p&gt;

&lt;p&gt;Our class is generic and it should be renamed. Maybe something like &lt;code&gt;NumberListReplacer&lt;/code&gt;, &lt;em&gt;not ideal&lt;/em&gt;, but more generic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NumberListReplacer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RuleInterface&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;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="k"&gt;for &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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getReplacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &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;rule&lt;/span&gt; &lt;span class="k"&gt;of&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;rules&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;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&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;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replacement&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;return&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fizBuzz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NumberListReplacer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzRule&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FizzRule&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BuzzRule&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fizBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// ex. replace all even numbers with a 'text'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;evenNumberReplacer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NumberListReplacer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;evenNumberReplacer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EvenNumberRule&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;evenNumberReplacer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &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;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Principles of Package Design: Creating Reusable Software Components&lt;/strong&gt; is a brilliant book by &lt;strong&gt;Matthias Noback&lt;/strong&gt;, it explains the SOLID principles brilliantly(and not only), the idea for the FizzBuzz implementation on example above is taken from there. &lt;a href="https://matthiasnoback.nl/book/principles-of-package-design/" rel="noopener noreferrer"&gt;https://matthiasnoback.nl/book/principles-of-package-design/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://khalilstemmler.com/articles/solid-principles/solid-typescript/" rel="noopener noreferrer"&gt;https://khalilstemmler.com/articles/solid-principles/solid-typescript/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>fizzbuzz</category>
      <category>interview</category>
      <category>typescript</category>
      <category>solid</category>
    </item>
  </channel>
</rss>
