<?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: Sam Hall</title>
    <description>The latest articles on DEV Community by Sam Hall (@hallsamuel90).</description>
    <link>https://dev.to/hallsamuel90</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%2F370393%2F263ef63a-8090-42cf-a43f-28d5b201e65d.jpg</url>
      <title>DEV Community: Sam Hall</title>
      <link>https://dev.to/hallsamuel90</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hallsamuel90"/>
    <language>en</language>
    <item>
      <title>Backend Software Architecture Demystified ✨</title>
      <dc:creator>Sam Hall</dc:creator>
      <pubDate>Wed, 13 Jul 2022 21:16:48 +0000</pubDate>
      <link>https://dev.to/hallsamuel90/backend-software-architecture-demystified-5hl6</link>
      <guid>https://dev.to/hallsamuel90/backend-software-architecture-demystified-5hl6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you heard of any of these software architectures? : Ports and adapters, clean architecture, layered application, onion architecture, hexagonal, N-tiered, so on and so forth. Have you ever stared at one of these diagrams and thought “Yeah that sense, but how do I do it code?” I have as well, and I think it is a sentiment (at least in my experience) that many people share.&lt;/p&gt;

&lt;p&gt;That’s why today we are demystifying software architecture (the backend part at least) down to a few basic principles and techniques. My goal is by the end of this article you’ll hopefully see that all of these architectures are essentially the same, and to paraphrase Bruce Lee “The only style is no style”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dedicated business logic layer
&lt;/h2&gt;

&lt;p&gt;The foundational building block in all of these architectures is a dedicated business logic layer. So let us start there.&lt;/p&gt;

&lt;p&gt;What &lt;em&gt;is&lt;/em&gt; business logic? It’s is the brains behind your application that fulfills use cases. What is a use case? Well its the thing you are trying to do. For example if we have a social media application, we might want to have the ability to “like” a post. So somewhere in our code we could have a function called &lt;code&gt;likePost&lt;/code&gt; or something like that.&lt;/p&gt;

&lt;p&gt;Riffing on this &lt;code&gt;likePost&lt;/code&gt; example, what are some requirements for this? We probably need to store some object (lets call it &lt;code&gt;PostLike&lt;/code&gt; ) and link it back to the &lt;code&gt;Post&lt;/code&gt; object. This would allow us to denote that the post has in fact been liked. &lt;code&gt;PostLike&lt;/code&gt; should probably also include who liked the post. Maybe we’d like to know when the &lt;code&gt;Post&lt;/code&gt; was liked. What happens if the &lt;code&gt;Post&lt;/code&gt; doesn’t exist? Should we verify that before creating this &lt;code&gt;PostLike&lt;/code&gt; object? Do other parts of the application need to be notified that someone liked a post? &lt;/p&gt;

&lt;p&gt;Some of these are explicitly required while some are implicitly required so that we save our ass so things don’t go sideways. In either case we can write tests for these things and ensure that our use cases &lt;strong&gt;behave&lt;/strong&gt; in the manor we expect. These are the business rules.&lt;/p&gt;

&lt;p&gt;Notice that thus far I haven’t mentioned &lt;code&gt;SQL&lt;/code&gt;, &lt;code&gt;DynamoDb&lt;/code&gt;, &lt;code&gt;RabbitMQ&lt;/code&gt;, &lt;code&gt;REST&lt;/code&gt;, &lt;code&gt;GraphQL&lt;/code&gt;, or any other technology for that matter. At this level we simply do not care. We are most concerned with “what” the behavior of the use case is, not “how” its going to happen. The business logic layer helps us drive &lt;strong&gt;behaviors&lt;/strong&gt; and technology solutions &lt;em&gt;do not&lt;/em&gt; fit within that category.&lt;/p&gt;

&lt;p&gt;Still, we are going to need to figure that part out if we are going to do anything useful with the business rules. This is a perfect segue into the next principle/technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency inversion
&lt;/h2&gt;

&lt;p&gt;If you are familiar with SOLID design principles, this is “D” part in the acronym and its states that&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;High level modules should not depend on low level modules; &lt;br&gt;
both should depend on abstractions. Abstractions should not depend on &lt;br&gt;
details.  Details should depend upon abstractions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While it is the official and accurate definition, in my opinion the language is much too complicated. It sounds scary. So what does dependency inversion actually mean?&lt;/p&gt;

&lt;p&gt;All it means is that instead of calling another function or method directly, you pass it in as an argument instead. So if you are working with classes in an object oriented language you would typically pass in some dependency through the constructor. If you are working with a language that supports first class functions, you would pass in a function as an argument to create a higher order function.&lt;/p&gt;

&lt;p&gt;Recall in the previous section that the business rules are looking to answer “what” not “how”, so one caveat is that these function signatures that we are passing in need to be agnostic of the underlying implementation. For example lets say we need to persist our &lt;code&gt;PostLike&lt;/code&gt; to some data store. We might do this with a function called &lt;code&gt;save&lt;/code&gt; that takes in a &lt;code&gt;PostLike&lt;/code&gt; object and returns the same object once it have been successfully persisted. Underneath the hood it could be writing to a &lt;code&gt;Postgres&lt;/code&gt; database or maybe even the file system.&lt;/p&gt;

&lt;p&gt;The benefit of passing in these dependencies is that it effectively decouples the business rules from any specific technology(aka loose coupling). Said differently this is the glue that holds everything together with the business rules. And its what allows us to tune the “what” and the “how” separately. We can change one without effecting the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show me the code
&lt;/h2&gt;

&lt;p&gt;Okay now that we’ve gotten the high-level stuff out of the way, lets dive into an example so we can see what this looks like in practice. We’ll layout the code for our &lt;code&gt;likePost&lt;/code&gt; use case and discuss on the other side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PostLike&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;accountId&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="nl"&gt;postId&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="nl"&gt;timestamp&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;type&lt;/span&gt; &lt;span class="nx"&gt;DoesPostExist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postId&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;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&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;type&lt;/span&gt; &lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;type&lt;/span&gt; &lt;span class="nx"&gt;PublishEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&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;likePost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;doesPostExist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;publishPostLikedEvent&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="nl"&gt;accountId&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="nl"&gt;postId&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="nl"&gt;doesPostExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DoesPostExist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;save&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostLike&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;publishPostLikedEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PublishEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostLike&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostLike&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;postExists&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;doesPostExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postId&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;postExists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cannot like post that does not exist...&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="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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;publishPostLikedEvent&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="k"&gt;return&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay so here we are! We have our &lt;code&gt;likePost&lt;/code&gt; function that takes in an &lt;code&gt;accountId&lt;/code&gt; and a &lt;code&gt;postId&lt;/code&gt; so that we can say that the account liked the post. In addition we have a couple of functions that we have passed in to help us flush out our use case. The &lt;code&gt;doesPostExist&lt;/code&gt; function (presumably supplied by the domain that handles &lt;code&gt;Posts&lt;/code&gt;) will let us know if the supplied &lt;code&gt;postId&lt;/code&gt; is valid or not. We have a &lt;code&gt;save&lt;/code&gt; function that will handle the persistence of the &lt;code&gt;PostLike&lt;/code&gt; and finally a &lt;code&gt;publishPostLikedEvent&lt;/code&gt; function that will notify stuff downstream that this has happened.&lt;/p&gt;

&lt;p&gt;We defined types for these functions but we did not define implementations. With our implementations of these functions (&lt;em&gt;shown off camera&lt;/em&gt;) we are free to choose whatever technologies we’d like. For example we could write an implementation for &lt;code&gt;publishPostLikedEvent&lt;/code&gt; that uses &lt;code&gt;SQS&lt;/code&gt; , &lt;code&gt;SNS&lt;/code&gt; , or &lt;code&gt;RabbitMQ&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;A good rule of thumb is if a function returns a &lt;code&gt;Promise&lt;/code&gt; just pass it in. Your unit tests will also thank you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagram it
&lt;/h2&gt;

&lt;p&gt;Despite what shape its presented in (hexagon, concentric circles, or boxes), the concept is the same. On the outside we have technology concerns and in the middle we have the actual business rules. For simplicity’s sake, lets look at a layered application diagram (the boxes) that fits with &lt;code&gt;likePost&lt;/code&gt; example above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P120OZ00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q04xbvnv2zl590lsuq1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P120OZ00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q04xbvnv2zl590lsuq1.jpeg" alt="Layered architecture diagram" width="480" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything above the business rules is usually some sort of facade or way to access the business rules. For example we could write a &lt;code&gt;REST&lt;/code&gt; api, &lt;code&gt;GraphQL&lt;/code&gt; , or even a &lt;code&gt;CLI&lt;/code&gt; . Sometimes you’ll see this referred to as the &lt;code&gt;I/O&lt;/code&gt; layer.&lt;/p&gt;

&lt;p&gt;Below the business rules are other potential layers driven by the business rules. We may need persistence, we may need to talk to another micro-service, third-party api, or what have you, and we may also need to publish an event to let other parts of the system know whats going on. &lt;/p&gt;

&lt;p&gt;These are fluid and can change on a case-by-case basis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The foundational pieces of software architectures are the behaviors that make up use cases.&lt;/li&gt;
&lt;li&gt;We can isolate these behaviors in a dedicated business logic layer.&lt;/li&gt;
&lt;li&gt;Dependency inversion is used to glue everything(layers) together.&lt;/li&gt;
&lt;li&gt;Using these techniques together separates “what” from “how” and allows the system to evolve naturally.&lt;/li&gt;
&lt;li&gt;Most popular software architectures work to achieve this although there are nuances between them.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Because of styles people are separated. Research your own experience, absorb what is useful, reject what is useless, add what is essentially your own.  -- Bruce Lee&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>typescript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>There and back again: Refactoring OO to FP</title>
      <dc:creator>Sam Hall</dc:creator>
      <pubDate>Mon, 13 Jun 2022 20:57:55 +0000</pubDate>
      <link>https://dev.to/hallsamuel90/there-and-back-again-refactoring-oo-to-fp-l8l</link>
      <guid>https://dev.to/hallsamuel90/there-and-back-again-refactoring-oo-to-fp-l8l</guid>
      <description>&lt;p&gt;Functional programming(FP) seems to be completely in vogue these days. While I do think FP has many benefits, I often have a hard time with what sometimes seems to me a dogmatic comparison that FP is superior than object oriented (OO) programming.&lt;/p&gt;

&lt;p&gt;Contrary to popular belief, I think that OO and FP are closer together than they might appear. At least this seems to be particularly true if the OO code is written with SOLID design principles in mind.&lt;/p&gt;

&lt;p&gt;In this article we are going to exploring a refactoring from SOLID object oriented(OO) code to a more functional programming (FP) style using Typescript. In addition to the “how-to” aspect, we’ll look at each refactoring from a testability perspective. I find it is a good gauge of code quality. If its easy to test, there is a high probability that there is not a bunch of funky state or hidden dependencies. &lt;/p&gt;

&lt;p&gt;Without further ado…. lets refactor!&lt;/p&gt;

&lt;p&gt;For this example we will use a very &lt;em&gt;very&lt;/em&gt; simplified bank account example. We’ll have an &lt;code&gt;Account&lt;/code&gt; domain object and our use case is opening a new account.&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;Account&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&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="nl"&gt;name&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="nl"&gt;accountStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CLOSED&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AccountDao&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;save&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Account&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="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AccountService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;accountDao&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AccountDao&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;openAccount&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&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="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&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="nl"&gt;name&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;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&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="na"&gt;accountStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accountDao&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&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;As you can see in this example, this is pretty typical SOLID code. We have some stateless service class that contains the business rules for our use case, and we hold a dependency on our data layer to be able to persist our account information. This is easily testable since we can inject a fake implementation using an in-memory database or mock.&lt;/p&gt;

&lt;p&gt;In our first refactoring to FP, we need to actually make this a function. And as they say, “a closure is a poor man’s object”. So lets turn this into a functional closure.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accountService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountDao&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AccountDao&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;openAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&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="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;id&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="nl"&gt;name&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;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="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;id&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="na"&gt;accountStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;accountDao&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;openAccount&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;Are we functional yet? Not quite. We could still potentially keep private state in this iteration, so lets remove the closure and bring in a higher-order function.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&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;saveAccount&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="nl"&gt;id&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="nl"&gt;name&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="nl"&gt;saveAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AccountDao&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;save&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="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;id&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="na"&gt;accountStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;saveAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&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;Hey this is pretty cool, we are passing in the dependency directly to the function, we factored out ability to keep state in the closure and its testable all the same. Its feels like an interface with one method and a built in constructor. I digg it.&lt;/p&gt;

&lt;p&gt;Still, there is work to do. Can we factor out the dependency all together? First we can take the creating of the account object and extract it to its own function.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&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="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&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="nl"&gt;name&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;span class="nx"&gt;Account&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;id&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="na"&gt;accountStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OPEN&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;p&gt;Notice that the &lt;code&gt;createAccount&lt;/code&gt; function is now pure. And instead of depending on the interface, we can just write our &lt;code&gt;saveAccount&lt;/code&gt; function implementation directly.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saveAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;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;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/accounts-store/accounts.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;account&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;account&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;Lastly we can compose the two to satisfy our use case.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uuid&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="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&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="nl"&gt;name&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;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;saveAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createAccount&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait, how is this testable!? We are unable to inject our fake &lt;code&gt;dao&lt;/code&gt; into the function. The answer here is that we &lt;em&gt;do not&lt;/em&gt; unit test the composition. Instead we unit test the pure parts which is very straight forward. In order to test the entire composition, we would need an integration test (a true testament to the name).&lt;/p&gt;

&lt;p&gt;In the end, maybe the goal is not the decision of OO or FP, but more so of stateless programming with clear responsibilities and limited coupling. &lt;/p&gt;

&lt;p&gt;Like most things in life, its not all black and white. Notice that all these refactorings were viable from the start. Each is stateless, testable, and has clear responsibilities! The main difference here is dependency management by using dependency inversion or dependency rejection.&lt;/p&gt;

&lt;p&gt;I think I'd like to conclude that maybe the balance lies somewhere in the middle. Personally, I have a preference towards the higher order function refactoring. It seems to have the best of both worlds in that it: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoids the spaghetti that can come along with classes and closures&lt;/li&gt;
&lt;li&gt;Doesn’t make things so fine grained that its hard to keep track of (functional composition)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe we can invent a new paradigm called FOOP? Thanks for reading!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>functional</category>
      <category>oop</category>
    </item>
    <item>
      <title>TDD Part 2: What is a Unit Test?</title>
      <dc:creator>Sam Hall</dc:creator>
      <pubDate>Fri, 22 Jan 2021 16:16:30 +0000</pubDate>
      <link>https://dev.to/hallsamuel90/tdd-part-2-what-is-a-unit-test-324</link>
      <guid>https://dev.to/hallsamuel90/tdd-part-2-what-is-a-unit-test-324</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In &lt;a href="https://dev.to/hallsamuel90/tdd-part-1-why-should-i-4a0e"&gt;part 1&lt;/a&gt; of the series, I shared my personal experience with TDD and how my practice with it has evolved. &lt;/p&gt;

&lt;p&gt;Before we dive too deep into it let's first answer what is a test, how to set up a test, and what defines some good characteristics of a unit test.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Unit Test? 🤔
&lt;/h1&gt;

&lt;p&gt;What is a unit test? For this, I like Elliotte Rusty Harrold's definition:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A Unit Test is a piece of code that verifies that a known, fixed input produces a known fixed output."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Okay now that we got that out of the way, what the hell do we do now!? I think this is probably best explained by the commonly known acronym AAA - no not the people you call when your car breaks down on the side of the road, what we are talking about here is Arrange Act Assert aka Given When Then.&lt;/p&gt;

&lt;p&gt;First, we need to arrange our known input. Then we feed that input into our method under test. Finally, we verify that the code did what we expected. Here are a couple of example tests of a calculator that takes an input of comma-separated strings.&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="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return 0 if the input is empty&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;emptyInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// arrange&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;calculator&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="nx"&gt;emptyInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// act&lt;/span&gt;

  &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//assert&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is simple enough that we can do this in one-line but under more complex circumstances (or if you are new to this) it is very helpful to break it out in this manner.&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="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return input if there is only one number&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;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calculator&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return sum of two numbers&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;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calculator&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1,2&lt;/span&gt;&lt;span class="dl"&gt;'&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;h1&gt;
  
  
  FIRST Principles 🥇
&lt;/h1&gt;

&lt;p&gt;Although this is a very simple example, let's take a second to make a few observations about these tests. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They are fast, there are no external dependencies. I'm not reading from the file system or database (we will cover this soon). This is good because I want to keep my feedback loop as tight as possible and I can keep running the tests between every change.&lt;/li&gt;
&lt;li&gt;They are isolated. I am only testing one thing in each test. If one of those breaks, I know exactly what broke and where to look.&lt;/li&gt;
&lt;li&gt;They are repeatable. It doesn't matter which order I run these in, what environment, they will always produce the same result.&lt;/li&gt;
&lt;li&gt;They are self-validating. I do not have to check manually if one of these failed. I will know on the run if something broke.&lt;/li&gt;
&lt;li&gt;They are thorough (at least somewhat here). Ideally you want to test your edge cases, error cases, and happy path. You need to know how you are going to handle everything.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are known as the FIRST principles of unit testing. Sometimes I feel that these are almost self-evident once you start writing tests, but I think it bears repeating and bolsters the definition of a unit test.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping Up
&lt;/h1&gt;

&lt;p&gt;Alright, that's lightweight stuff, what about functions and methods that don't return anything? What about if I need to talk to a database? You still haven't shown how to actually do test-driven development. &lt;/p&gt;

&lt;p&gt;Whoah.... cool the jets we will get there I promise. &lt;/p&gt;

&lt;p&gt;In the next article, we will start actually doing some TDD with an awesome way to learn and practice TDD - Code Katas.&lt;/p&gt;

&lt;p&gt;Thank you for reading and stay tuned! 🙏&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>testing</category>
      <category>codequality</category>
      <category>typescript</category>
    </item>
    <item>
      <title>TDD Part 1: Why Should I?</title>
      <dc:creator>Sam Hall</dc:creator>
      <pubDate>Fri, 18 Dec 2020 16:24:00 +0000</pubDate>
      <link>https://dev.to/hallsamuel90/tdd-part-1-why-should-i-4a0e</link>
      <guid>https://dev.to/hallsamuel90/tdd-part-1-why-should-i-4a0e</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In the first part of this series I want to share my personal experience with test-driven development(TDD), how I got there, and how it makes the development process much simpler with an end result of higher quality code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bad Tests 👎
&lt;/h1&gt;

&lt;p&gt;I once worked on a project using a micro-services architecture that had a contractual obligation for 80% code coverage. Before this most of us had not written unit tests, let alone practiced TDD.&lt;/p&gt;

&lt;p&gt;In the beginning, I developed the way I normally did at the time, that is slam out a bunch of code, run the application, wonder why it wasn't working, run the debugger, fix the bug, rinse and repeat(also known as bug driven development). &lt;/p&gt;

&lt;p&gt;I would write the unit tests after I finished the code. Sometimes I would even create another task to do this work under after I had already committed the production code(no bueno). It was deeply frustrating and oftentimes took longer to write the tests than it did the feature (the tests were also garbage).&lt;/p&gt;

&lt;h1&gt;
  
  
  Starting to Write Better Tests 🌱
&lt;/h1&gt;

&lt;p&gt;As the system grew and more services were added, it became increasingly more difficult to develop this way. Running the entire system in a local environment was not always feasible and the feedback loop was far too long to do anything efficiently.&lt;/p&gt;

&lt;p&gt;As my frustration grew I started looking at how to write better unit tests and how to write testable code. I read &lt;a href="https://amzn.to/34kTzQ9"&gt;Clean Code&lt;/a&gt; which is closely related but not quite directed at TDD, discovered the &lt;a href="https://www.youtube.com/watch?v=rtmFCcjEgEw&amp;amp;list=PLGbeNLNjS1rHkib_aXeIUrV7YhSbQPz2g&amp;amp;index=36&amp;amp;ab_channel=LaraconEU"&gt;SOLID design principles&lt;/a&gt;, and absorbed as much as I could from the internet. &lt;/p&gt;

&lt;p&gt;So I started writing a little bit of code and then I would write the unit tests at the same time. This kept my code clean, and I could develop entire features without ever firing up the application. The tests were all of the feedback I needed and then I could verify that the system was running as expected less frequently. The issues that did occur where usually plumbing related or not understanding the problem correctly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Going full TDD 💡
&lt;/h1&gt;

&lt;p&gt;I then came across this &lt;a href="https://www.youtube.com/watch?v=fr1E9aVnBxw&amp;amp;ab_channel=Devoxx"&gt;talk by Elliotte Rusty Harold&lt;/a&gt;, and one of the audience members basically described how I developed and asked why he should write his tests first. Rusty's response was to the effect of 'so you are writing a little code, writing a little test, writing a little code, etc... I'm just asking that you cut out the first step and write a little test, write a little code.' &lt;/p&gt;

&lt;p&gt;A light bulb went off and that's what I started doing. Before I wrote any code, I wrote a test first. Suddenly writing complex features became not only easy but fun! I knew what the system had to do, so I would write down a list of tests, and one by one I would write the test, then write the code that made it pass. This let me build up the feature in tiny baby steps and I got immediate feedback, kept the code simple and clean, and gave me confidence in the code that I had not experienced in any other way. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion 🔚
&lt;/h1&gt;

&lt;p&gt;There are many other benefits to TDD documented elsewhere, but I wanted to explain my evolution of how I got there and how it affected me practically. &lt;/p&gt;

&lt;p&gt;I would say that writing the tests as you write the code gives you about 80% of the benefits but going full TDD will take all unneeded complexity out of the design and leaves you with higher quality than you might have had otherwise. &lt;/p&gt;

&lt;p&gt;The bottom line is, is that it makes coding easier and with the added bonus that your code will be by default high quality.&lt;/p&gt;

&lt;p&gt;Throughout the rest of this series, I'll be going over the basic anatomy of tests, test doubles (mocks), how to write tests for legacy code, and how to practice TDD.&lt;/p&gt;

&lt;p&gt;I hope you'll join me! &lt;/p&gt;

&lt;p&gt;P.S. If you are wondering why there is a surgeon washing his hands as the cover image. Robert C. Martin(aka Uncle Bob) describes the technical discipline of TDD as akin to the ritual of a surgeon meticulously washing his/her hands or double-entry bookkeeping in accounting. Sometimes seemingly arbitrary but highly effective.&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>testing</category>
      <category>codequality</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
