<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>imperative &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<atom:link href="https://jessewarden.com/tag/imperative/feed" rel="self" type="application/rss+xml" />
	<link>https://jessewarden.com</link>
	<description>Software &#124; Fitness &#124; Gaming</description>
	<lastBuildDate>Tue, 26 Jun 2018 19:26:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://jessewarden.com/wp-content/uploads/2016/08/cropped-Lambda2-32x32.png</url>
	<title>imperative &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<link>https://jessewarden.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 6</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:29:15 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5566</guid>

					<description><![CDATA[Next, Logging, and Conclusions Welcome to Part 6, the final installment in this series. Below we cover unit testing the noop next, how to create pure functions that wrap noop so you can compose them, and finally using code coverage to strategically hit the last code that&#8217;s not covered. Contents This is a 6 part [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Next, Logging, and Conclusions</h1>
<p>Welcome to Part 6, the final installment in this series. Below we cover unit testing the noop <code>next</code>, how to create pure functions that wrap <code>noop</code> so you can compose them, and finally using code coverage to strategically hit the last code that&#8217;s not covered.<br />
<span id="more-5566"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 6.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>Next is Next</h1>
<p>The last part is deal with <code>next</code>. THIS is where I&#8217;d say it&#8217;s ok to use mocks since it&#8217;s a <code>noop</code>, but you do want to ensure it was called at least once, without an <code>Error</code> in the happy path, and with an <code>Error</code> in the bad path.</p>
<p>&#8230; but you&#8217;ve made it this far which means you are FAR from ok, you&#8217;re amazing. NO MOCKS!</p>
<p>Here&#8217;s the basic&#8217;s of testing noops. You sometimes KNOW if they did something, or how they can affect things based on their arguments. In <code>next</code>&#8216;s case, he&#8217;ll signal everything is ok if passed no arguments, and something went wrong and to stop the current connect middleware chain if an <code>Error</code> is passed, much like a <code>Promise</code> chain. We also know that <code>next</code> always returns <code>undefined</code>.</p>
<h2>Ors (Yes, Tales of Legendia was bad)</h2>
<p>One simple way is to just inject it into the existing Promise chain we have:</p>
<pre><code class="javascript">.then( info =&gt; next() || Promise.resolve(info))
.catch( error =&gt; next(error) || Promise.reject(error)))
</code></pre>
<p>This&#8217;ll make the connect middleware happy as well as satisfying our unit tests expecting either an email info out, or a rejected promise with error.</p>
<h2>Pass Through</h2>
<p>Much like you log <code>Promise</code> or other Monad chains, simply make a pass through function.</p>
<pre><code class="javascript">const nextAndResolve = curry((next, info) =&gt; next() || Promise.resolve(info))
const nextAndError = curry((next, error) =&gt; next(error) || Promise.reject(error))
</code></pre>
<p>And since we already know what the <code>next</code> is, we can just attach &#8217;em to the end of the <code>Promise</code> chain, similar to above:</p>
<pre><code class="javascript">.then(nextAndResolve(next))
.catch(nextAndError(next))
</code></pre>
<p>&#8220;Wat!?&#8221; you may be saying, &#8220;all you did was wrap that previous example in functions&#8221;. Yup, they&#8217;re pure, and you can test those in isolation vs. test that gigantic Promise chain with 20 billion stubs.</p>
<pre><code class="javascript">describe('nextAndResolve when called', ()=&gt; {
    it('should fulfill', () =&gt; {
        return expect(nextAndResolve(noop, 'info')).to.be.fulfilled
    })
    it('should resolve', () =&gt; {
        return expect(nextAndResolve(noop, 'info')).to.become('info')
    })
})
</code></pre>
<p>Let&#8217;s do the same for error:</p>
<pre><code class="javascript">describe('nextAndError when called', ()=&gt; {
    it('should fulfill', () =&gt; {
        return expect(nextAndError(noop, new Error('they know what is what'))).to.be.rejected
    })
    it('should resolve', () =&gt; {
        const datBoom = new Error('they just strut')
        return expect(nextAndError(noop, datBoom)).to.rejectedWith(datBoom)
    })
})
</code></pre>
<p><img fetchpriority="high" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.43.09-PM.png" alt="" width="424" height="236" class="alignleft size-full wp-image-5544" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.43.09-PM.png 424w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.43.09-PM-300x167.png 300w" sizes="(max-width: 424px) 100vw, 424px" /></p>
<p style="clear: both;">&nbsp;</p>
<p style="clear: both;">If you&#8217;re Spidey Sense left over from your Imperative/OOP days is tingling, and you really want to create a mock or <a href="http://sinonjs.org/releases/v6.0.0/spies/">spy</a>, go for it.</p>
<p>I would rather you focus your time on creating pure Promise chains vs. investing in better testing side effects using the connect middleware.</p>
<h1>Mopping Up</h1>
<p>Only 2 functions to go, and we&#8217;re up in dem hunneds <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4af.png" alt="💯" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</p>
<h2>sendEmail &#8230; or not</h2>
<p><img decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-1024x108.png" alt="" width="525" height="55" class="alignleft size-large wp-image-5546" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-1024x108.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-300x32.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-768x81.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM.png 1704w" sizes="(max-width: 525px) 100vw, 525px" /></p>
<p>The <code>sendEmailOrNext</code> is a textbook case of copy-pasta coding. We&#8217;ll duplicate our previous <code>sendEmail</code> unit tests since they have some yum yum stubs:</p>
<pre><code class="javascript">describe('sendEmailOrNext when called', ()=&gt; {
    ...
    const reqStubNoFiles = { cookie: { sessionID: '1' } }
    ...
    it('should work with good stubs', ()=&gt; {
        return expect(
            sendEmailOrNext(
                readFileStub,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStub,
                resStub,
                nextStub
            )
        ).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(
            sendEmailOrNext(
                readFileStubBad,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStub,
                resStub,
                nextStub
            )
        ).to.be.rejected
    })
    it('should resolve with false if no files', ()=&gt; {
        return expect(
            sendEmailOrNext(
                readFileStub,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStubNoFiles,
                resStub,
                nextStub
            )
        ).to.become(false)
    })
})
</code></pre>
<p>I&#8217;ve left out all the stubs, save the new one that shows, if we have no files, it just bypasses the entire thing, calls <code>next</code> with no value signaling to connect we&#8217;re good to go and finished, but still returning a useful value of <code>false</code> to say we didn&#8217;t do what we&#8217;re supposed to since we couldn&#8217;t find any files.</p>
<h2>There And Back Again</h2>
<p><img decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-1024x117.png" alt="" width="525" height="60" class="alignleft size-large wp-image-5548" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-1024x117.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-300x34.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-768x88.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM.png 1386w" sizes="(max-width: 525px) 100vw, 525px" /></p>
<p>Oh look, coverage found yet another <code>noop</code>, imagine that.</p>
<pre><code class="javascript">const logPort = port =&gt; console.log(`Example app listening on port ${port}!`) || true
</code></pre>
<p>And the 1 test:</p>
<pre><code class="javascript">describe('logPort when called', ()=&gt; {
    it('should be true with a port of 222', ()=&gt; {
        expect(logPort(222)).to.equal(true)
    })
})
</code></pre>
<h1>Should You Unit Test Your Logger!?</h1>
<p>If you really want to create a mock/spy for <code>console.log</code>, I admire your tenacity, <a href="https://www.haskell.org/">Haskell</a> awaits you with open arms in your future. Remember me when you&#8217;re at the top and you&#8217;ve bested <a href="http://dragonball.wikia.com/wiki/Mr._Popo">Mr. Popo</a> on the Lookout.</p>
<p>&#8230; however, if you&#8217;re not using <code>console.log</code>, and instead using a known Node logger like <a href="https://github.com/pinojs/pino">Pino</a>, well, heh, you SHOULD!</p>
<p>I should point out some well known <a href="https://clojure.org/">Clojure</a> guys think I&#8217;m going overboard:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.04.34-PM-2.png" alt="" width="630" height="601" class="alignleft size-full wp-image-5549" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.04.34-PM-2.png 630w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.04.34-PM-2-300x286.png 300w" sizes="auto, (max-width: 630px) 100vw, 630px" /></p>
<p>If you read <a href="https://twitter.com/danielglauser/status/998228883034882049">the Twitter thread</a>, an <a href="http://elm-lang.org/">Elm</a> guy schools me, and the Haskell cats show me how even there you can trick Haskell, but still acknowledge (kind of?) the purity pain.</p>
<h1>Conclusions</h1>
<p>Running coverage, we get:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM.png" alt="" width="976" height="144" class="alignleft size-full wp-image-5550" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM.png 976w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM-300x44.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM-768x113.png 768w" sizes="auto, (max-width: 976px) 100vw, 976px" /></p>
<p>Welcome to hunneds country. Congratulations on making this far, and not one import of <a href="http://sinonjs.org/">sinon</a> to be found. Don&#8217;t worry, deadlines and noops are all over the place in the JavaScript world, and sinon&#8217;s mock creation ability is not something to be shunned, but embraced as a helpful addition to your toolset. Like all technical debt, create it intentionally with notes about why, what to remove, context around creating it, etc in code comments around it.</p>
<p>Hopefully you&#8217;ve seen how creating small, pure functions, makes unit testing with small stubs a lot easier, faster, and leads to more predictable code. You&#8217;ve seen how you can use Functional Programming best practices, yet still co-exist with noops in imperative code, and classes and scope in OOP.</p>
<p>I should also point out that writing imperative or OOP code like this is a great way to learn how to write FP. Sometimes our brains are wired to flesh out ideas in those styles, and that&#8217;s great. Whatever works to get the ideas down. On the front-end, using vanilla React&#8217;s classes vs. <a href="https://github.com/acdlite/recompose">recompose</a>&#8230; or even just components functions only. Functional Programming will still hurt just as much as Imperative or OOP if you&#8217;ve got a not-so-figured out idea on how some problems should be solved and structured. Write it so it feels comfortable, the refactor &amp; test to purity.</p>
<p>You&#8217;ve seen how to compose these functions together synchronously via operands like <code>&amp;&amp;</code> and <code>||</code>, using <a href="https://lodash.com/docs/4.17.10#flow">flow</a>/<a href="https://ramdajs.com/docs/#compose">compose</a>. You&#8217;ve also seen how to compose them in <code>Promise</code> chains and <code>Promise.all</code>, curried or not.</p>
<p>You&#8217;ve also seen how 100% unit test coverage in a FP code base still has bugs that are only surfaced with concrete implementations using integration testing, such as with <a href="http://www.mbtest.org/">Mountebank</a>.</p>
<p>Node is often used for API&#8217;s that have little to no state and are just orchestration layers for a variety of XML <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a>, <a href="https://www.json.org/">JSON</a>, and text. The no mutable state of Functional Programming works nicely with that concept in ensuring those no state to debug.</p>
<p>Conversely, if you&#8217;re dealing with a lot of state such as database connections and streaming text files, not only can you see how you can test such challenging areas using pure functions, but also how many of those things can be run at the same time to speed things up with stepping on each other through global variables.</p>
<p>Props to <a href="http://cliffmeyers.com/">Cliff Meyers</a> for teaching me what <a href="http://www.mbtest.org/">Mountebank is</a>.</p>
<h1>Code &amp; Help</h1>
<p>The <a href="https://github.com/JesterXL/fp-node">Code is on Github</a>. Got any questions, hit me up on <a href="https://www.youtube.com/user/jesterxl">YouTube</a>, <a href="https://twitter.com/jesterxl">Twitter</a>, <a href="https://www.facebook.com/">Facebook</a> (I&#8217;m Jesse Warden), or <a href="jesterxl@jessewarden.com">drop me an email</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 5</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:28:48 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5564</guid>

					<description><![CDATA[Noops, Stub Soup, and Mountebank Welcome to Part 5 where we cover more about noops with a utility to test them, the &#8220;stub soup&#8221; that can happen if you don&#8217;t create small pure functions, and how we can utilize stubs instead of mocks to unit test larger functions. The most important part, though, is setting [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Noops, Stub Soup, and Mountebank</h1>
<p>Welcome to Part 5 where we cover more about noops with a utility to test them, the &#8220;stub soup&#8221; that can happen if you don&#8217;t create small pure functions, and how we can utilize stubs instead of mocks to unit test larger functions. The most important part, though, is setting up <a href="http://www.mbtest.org/">Mountebank</a> to show how integration tests can show problems in your unit tests despite 100% coverage. We use wrapping <code>class</code> instances as an example to show you the pitfalls <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">Object Oriented Programming</a> code can make for you.<br />
<span id="more-5564"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 5.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>The Final Battle?</h1>
<p>At this point, we&#8217;ve shrunk our <a href="https://expressjs.com/en/guide/routing.html">Express route</a> as much as we&#8217;re going to without some serious refactoring. Let&#8217;s unit test it using (read copy pasta) all the stubs we&#8217;ve already made.</p>
<h2>Noops</h2>
<p>Before we proceed, let&#8217;s explain what a <code>noop</code> is. Pronounced &#8220;no awp&#8221;, it&#8217;s slang for &#8220;no operation&#8221;. It means a function that doesn&#8217;t return a value so it apparently has no effect because we have no proof it did any operation. That isn&#8217;t true; we all live and die by <code>console.log</code> which always returns <code>undefined</code>. If you run in <a href="https://aws.amazon.com/ecs/">ECS</a>, all those <code>console.log</code> calls are putting text in standard out and you&#8217;re probably collecting all those logs for into <a href="https://www.elastic.co/elk-stack">ELK</a> or <a href="https://aws.amazon.com/cloudwatch/">CloudWatch</a> or <a href="https://www.splunk.com/">Splunk</a>. That&#8217;s certainly an &#8220;operation with noticeable effect&#8221;. Functional Programmers call that a &#8220;side effect&#8221; of the function.</p>
<p>Often you&#8217;ll stub them in unit tests like <code>() =&gt; undefined</code> or the less clear, but shorter <code>() =&gt; {}</code>. Save yourself some typeing and use Lodash&#8217; <a href="https://lodash.com/docs/4.17.10#noop">noop</a>, Ramda <a href="https://ramdajs.com/docs/#always">always</a> if you&#8217;re a Ramda purist or <a href="https://char0n.github.io/ramda-adjunct/2.7.0/RA.html#.noop">noop</a> in Ramda Adjunct.</p>
<h2>My God, It&#8217;s Full Of Stubs</h2>
<p>Here&#8217;s the unit test with stubs needed above it for <code>sendEmail</code> t3h lelz:</p>
<pre><code class="javascript">describe('sendEmail when called', ()=&gt; {
    const readFileStub = (path, encoding, callback) =&gt; callback(undefined, 'email')
    const configStub = { has: stubTrue, get: () =&gt; 'email service' }
    const createTransportStub = () =&gt; ({
        sendEmail: (options, callback) =&gt; callback(undefined, 'info')
    })
    const getUserEmailStub = () =&gt; 'email'
    const renderStub = stubTrue
    const reqStub = {
        cookie: { sessionID: '1' },
        files: [{scan: 'clean', originalname: 'so fresh', path: '/o/m/g'}]
    }
    const resStub = {}
    const nextStub = noop
    it('should work with good stubs', ()=&gt; {
        return expect(
            sendEmail(
                readFileStub,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStub,
                resStub,
                nextStub
            )
        ).to.be.fulfilled
    })
})
</code></pre>
<p>A successful test, but the stubs, while succinct, almost outnumber the lines of code for the test. As you can see, Functional Programming, even when attempted with best effort, doesn&#8217;t necessarily &#8220;solve&#8221; your unit tests having to create a lot of &#8220;test code&#8221;. Mocks often get a bad rap for being verbose and hard to maintain. Stubs I believe are included in this, but at least with stubs they&#8217;re smaller, easier, and &#8220;mostly pure&#8221;. Still, as soon as you refactor your implementation, you&#8217;ll have to fix your tests, and sometimes your stubs will have to change too.</p>
<p>Trust me, this is much more preferable than to refactoring mocks.</p>
<p>The best thing to do is remember your training of the basics, like <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY: don&#8217;t repeat yourself</a>, and keep your tests organized with commonly used good and bad stubs within reach (meaning you don&#8217;t have to scroll too far to read them). Like OOP, FP functions should be short and focused to be re-usable, and most importantly, composeable. It&#8217;s hard and gets easier with practice. A fully fleshed out idea of the problem you&#8217;re trying to solve helps a lot, don&#8217;t be afraid to prototype in imperative code.</p>
<h2>sendEmail Unit Tests</h2>
<p>Let&#8217;s add the failing which is easy because basically any stub could fail and the whole function fails:</p>
<pre><code class="javascript">it('should fail when reading files fails', ()=&gt; {
    return expect(
        sendEmail(
            readFileStubBad,
            configStub,
            createTransportStub,
            getUserEmailStub,
            renderStub,
            reqStub,
            resStub,
            nextStub
        )
    ).to.be.rejected
})
</code></pre>
<p>And the most important, what <code>sendEmail</code> eventually resolves to. Yes, returning a Promise every time is important, but let&#8217;s ensure it resolves to something:</p>
<pre><code class="javascript">it('should resolve to an email sent', ()=&gt; {
    return sendEmail(
        readFileStub,
        configStub,
        createTransportStub,
        getUserEmailStub,
        renderStub,
        reqStub,
        resStub,
        nextStub
    )
    .then(result =&gt; {
        expect(result).to.equal('info')
    })
})
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.05.03-AM.png" alt="" width="586" height="178" class="alignleft size-full wp-image-5535" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.05.03-AM.png 586w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.05.03-AM-300x91.png 300w" sizes="auto, (max-width: 586px) 100vw, 586px" /></p>
<p>And coverage is now:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-1024x438.png" alt="" width="525" height="225" class="alignleft size-large wp-image-5536" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-1024x438.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-300x128.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-768x329.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM.png 1472w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>The feels.</p>
<h1>Class Composition is Hard, Get You Some Integration Tests</h1>
<p>Sadly, this is where Functional Programming and Object Oriented Programming stop working together. Our code has a bug that you won&#8217;t find in unit tests, only integration tests. In languages like JavaScript, <a href="https://www.python.org/">Python</a>, and <a href="https://www.lua.org/">Lua</a>, when you call functions on Classes without the class attached, they&#8217;ll often lose scope (<code>this</code> or <code>self</code> will be <code>undefined</code>/<code>nil</code>). Eric Elliot breaks down the details of a lot of these cases in his article <a href="https://medium.com/javascript-scene/why-composition-is-harder-with-classes-c3e627dcd0aa">Why Composition is Harder With Classes</a>.</p>
<p>Integration tests using <a href="https://github.com/visionmedia/supertest">Supertest</a> or <a href="http://www.mbtest.org/">Mountebank</a> help with different levels of integration tests. We&#8217;ll use Mountebank in this article. Suffice to say your unit tests are only as good as the stubs you provide. The stubs you provide basically fake or emulate functionality of the dependencies and are as small and simple as possible. Stubs are different code than the concrete (real) implementations, and unless they capture it exactly, don&#8217;t always test the same. You&#8217;ll see an example of this below testing OOP code.</p>
<h2>Pitfalls When Stubbing Class Methods</h2>
<p>Notice none of our stubs use any classes or Object.prototype, and yet, this is exactly how <code>nodemailer</code> works. It all comes down to class instances losing their <code>this</code> scope. Let&#8217;s write a basic pure wrapper around nodemailer, unit test it, show it pass, then setup Mountebank so we can show it breaks at runtime when you use the real nodemailer vs. stubs. Given Mountebank is a large topic, I won&#8217;t cover too much how it works, but the <a href="https://github.com/JesterXL/fp-node/blob/master/test-integration/setupMountebank.js">code is included</a>. Just know it&#8217;ll listen on the email port, act like an email server, and send real email responses so nodemailer believes it truly is sending an email.</p>
<p>Let&#8217;s create a <code>sandbox.js</code> file to play and a <code>sandbox.test.js</code> in the tests folder.</p>
<pre><code class="javascript">const nodemailer = require('nodemailer')

const sendEmailSafe = (createTransport, mailOptions, options) =&gt;
    new Promise((success, failure) =&gt; {
        const { sendMail } = createTransport({mailOptions})
        sendMail(options, (err, info) =&gt;
            err
            ? failure(err)
            : success(info))
    })

module.exports = sendEmailSafe
</code></pre>
<p>And the unit test:</p>
<pre><code class="javascript">...
describe.only('sendEmailSafe when called', ()=&gt; {
    it('should work with good stubs', () =&gt; {
        const createTransportStub = () =&gt; ({
            sendMail: (options, callback) =&gt; callback(undefined, 'email sent')
        })
        return sendEmailSafe(createTransportStub, {}, {})
        .then(result =&gt; {
            expect(result).to.equal('email sent')
        })
    })
})
...
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-12.12.12-PM.png" alt="" width="444" height="174" class="alignleft size-full wp-image-5537" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-12.12.12-PM.png 444w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-12.12.12-PM-300x118.png 300w" sizes="auto, (max-width: 444px) 100vw, 444px" /></p>
<h2>Integration Test</h2>
<p>So it passes. Let&#8217;s try with the integration test that uses a real nodemailer instance vs. our unit test stubs. I&#8217;ve setup mountebank to listen on port 2626 at localhost for emails. If someone sends an email with the from address equaling &#8220;jesterxl@jessewarden.com&#8221;, it&#8217;ll respond with an &#8220;ok the email was sent, my man&#8221;. Before we automate this, let&#8217;s do it manually first.</p>
<h3>Setting Up Mountebank</h3>
<p>Run <code>npm i mountebank --save-dev</code> first, then once it is complete, open your package.json and add this script:</p>
<pre><code class="json">"scripts": {
    ...
    "mb": "npx mb"
  },
...
</code></pre>
<p>Now when you run <code>npm run mb</code>, it&#8217;ll run Mountebank. It&#8217;ll basically start a Node server on port 2525. As long as it&#8217;s running, you can send it JSON to add imposters (mocks for running services).</p>
<h3>Setting Up Your Imposters</h3>
<p>An imposter is basically a mock or stub for services. Typically <a href="https://martinfowler.com/articles/mocksArentStubs.html">mocks and stubs</a> are used for unit tests and are created in code. In Mountebank, however, you create one by sending Mountebank REST calls. For example a POST call, typically on localhost:2525. You send it JSON describing what port it&#8217;s supposed to listen on, what other things to look for, and what JSON &amp; headers to respond with. Mountebank will then spawn a service on that port listening for incoming connections. If the request has attributes it recognizes (you do a GET on port 9001 with a path of <code>/api/health</code>, you send an email on port 2626 from &#8216;cow@moo.com&#8217;, etc), it&#8217;ll respond with whatever stub you tell it too. For example, some hardcoded JSON with an HTTP 200 status code. While stubs typically respond immediately or with Promises, these respond as a REST response.</p>
<p>Check out the import top part of our <code>setupMountebank.js</code> that I&#8217;ve placed in the &#8220;test-integration&#8221; folder:</p>
<pre><code class="javascript">...
const addNodemailerImposter = () =&gt;
    new Promise((success, failure)=&gt;
        request({
            uri: 'http://localhost:2525/imposters',
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            body: JSON.stringify({
                protocol: 'smtp',
                port: 2626,
                stubs: [{
                    predicates: [
                        {
                            contains: {
                                from: 'jesterxl@jessewarden.com'
                            }
                        }
                    ]
                }]
            })
        },
    ...
</code></pre>
<p>As you can see, a simple POST request to tell Mountebank, &#8220;Yo, if any dude sends an email on port 2626 and it is from me, respond it worked&#8221;. Typically Mountebank wants to define that response in the stubs Array, but for emails, you can leave it blank and it&#8217;ll default to a success response. At the time of this writing, there is no way to make an email fail, only REST calls. As long as Mountebank is running, it&#8217;ll remember to do this unless you delete it, or close Mountebank.</p>
<p>Now, to play around, I&#8217;ve run it manually to register. Check the bottom code:</p>
<pre><code class="javascript">if (require.main === module) {
    Promise.all([
        addNodemailerImposter()
    ])
    .then(() =&gt; console.log('Mountebank Imposters initialized successfully.'))
    .catch(error =&gt; console.error('Mountebank Imposters failed:', error))
}
</code></pre>
<p>Open a new terminal, and run <code>node test-integration/setupMountebank.js</code>, and you should see the Mountebank terminal light up:</p>
<pre><code class="shell">&gt; npx mb

info: [mb:2525] mountebank v1.14.1 now taking orders - point your browser to http://localhost:2525 for help
info: [mb:2525] POST /imposters
info: [smtp:2626] Open for business...
</code></pre>
<p>That &#8220;Open for business&#8230;&#8221; line is key; that means Mountebank understood what you want and worked and you can now send emails to port 2626. Let&#8217;s do that.</p>
<h3>Sending the Email</h3>
<p>Open up <code>sandbox.js</code> and check the code that&#8217;ll run if we use Node to run it:</p>
<pre><code class="javascript">if (require.main === module) {
    sendEmailSafe(
        nodemailer.createTransport,
        {
            host: 'localhost',
            port: 2626,
            secure: false
        },
        {
            from: 'jesterxl@jessewarden.com',
            to: 'jesterxl@jessewarden.com',
            subject: 'what you hear, what you hear is not a test',
            body: 'Dat Body Rock'
        }
    )
    .then(result =&gt; {
        console.log("result:", result)
    })
    .catch(error =&gt; {
        console.log("error:", error)
    })
}
</code></pre>
<h3>Swing and a Miss</h3>
<p>Rad, now try to send an email via <code>node src/sandbox.js</code>:</p>
<pre><code class="javascript">error: TypeError: Cannot read property 'getSocket' of undefined
    at sendMail (/Users/jessewarden/Documents/_Projects/fp-node/node_modules/nodemailer/lib/mailer/index.js:143:25)
...
</code></pre>
<p>Whoa, wat? Let&#8217;s go into Nodemailer&#8217;s sourcecode and see what the heck is going on:</p>
<pre><code class="javascript">/* node_modules/nodemailer/lib/mailer/index.js line 134 */
sendMail(data, callback) {
    ...
        /* broken below this comment */
    if (typeof this.getSocket === 'function') {
        this.transporter.getSocket = this.getSocket;
        this.getSocket = false;
    }
...
</code></pre>
<p>It&#8217;s doing a type check to see if <code>this.getSocket</code> is a function vs. a Boolean. That&#8217;s fine, but they should of check for <code>this</code> being undefined first.</p>
<p>Or should they? Once you&#8217;re in class world, and you&#8217;ve been doing OOP for awhile, you shouldn&#8217;t have to check for <code>this</code>; it&#8217;s just a normal part of how classes work. If it doesn&#8217;t, something more fundamental is messed up, the most common being forgetting to setup <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind">bind</a> in the constructor for callbacks for example.</p>
<p>We&#8217;re not going to fix Nodemailer to make it more friendly to FP developers. In fact, this is a common trend in that many libraries you use both in Node and in the Browser (i.e. from node_modules) will be written in all sorts of ways. You need to be accommodating.</p>
<p>Instead, we&#8217;ll assume that we&#8217;re not allowed to call <code>sendEmail</code> alone, and ensure it&#8217;s always <code>something.sendEmail</code>; whatever to the left is the instance, and will retain scope if you call it like that. This is why a lot of my examples you&#8217;ll see I&#8217;ll make <code>fs</code> the dependency and then call <code>fs.readFile</code> vs. just <code>readFile</code>.</p>
<h3>FP-Fu</h3>
<p>Let&#8217;s first fix our implementation to be OOP friendly, and ensure the tests still work, else fix &#8217;em. The old code:</p>
<pre><code class="javascript">const { sendEmail } = createTransport({mailOptions})
        sendMail(options, (err, info) =&gt;
</code></pre>
<p>The new code:</p>
<pre><code class="javascript">const transport = createTransport({mailOptions})
        transport.sendMail(options, (err, info) =&gt;
</code></pre>
<p>Re-run the tests:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-3.38.23-PM.png" alt="" width="476" height="186" class="alignleft size-full wp-image-5539" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-3.38.23-PM.png 476w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-3.38.23-PM-300x117.png 300w" sizes="auto, (max-width: 476px) 100vw, 476px" /></p>
<p style="clear: both;">&nbsp;</p>
<p style="clear: both;">Cool, the original public interface still works and hides the OOPy stuff. Let&#8217;s test the integration test now with sending a real email with real, concrete implementation vs. stubs:</p>
<pre><code class="shell">result: { accepted: [ 'jesterxl@jessewarden.com' ],
  rejected: [],
  envelopeTime: 3,
  messageTime: 3,
  messageSize: 590,
  response: '250 2.0.0 Ok: queued as f19f95e62da4afeade02',
  envelope:
   { from: 'jesterxl@jessewarden.com',
     to: [ 'jesterxl@jessewarden.com' ] },
  messageId: '&lt;ab0bab09-7628-007b-f497-3d53806704ae@jessewarden.com&gt;' }
</code></pre>
<p>I was like Whee!!! Let&#8217;s fix our original implementation now that we&#8217;ve proven we know how to wrangle OOP with FP now. We&#8217;ll change:</p>
<pre><code class="javascript">...
sendEmailSafe(
  createTransport(
    createTransportObject(emailService.host, emailBody.port)
  ).sendEmail,
...
</code></pre>
<p>To:</p>
<pre><code class="javascript">...
sendEmailSafe(
  createTransport(
    createTransportObject(emailService.host, emailBody.port)
  ),
...
</code></pre>
<p>And switch <code>sendEmailSafe</code>:</p>
<pre><code class="javascript">const sendEmailSafe = curry((sendEmailFunction, mailOptions) =&gt;
  new Promise((success, failure) =&gt;
    sendEmailFunction(mailOptions, (err, info) =&gt;
      err
      ? failure(err)
      : success(info)
    )
  )
)
</code></pre>
<p>To the new OOP-friendly version:</p>
<pre><code class="javascript">const sendEmailSafe = curry((transport, mailOptions) =&gt;
  new Promise((success, failure) =&gt;
    transport.sendEmail(mailOptions, (err, info) =&gt;
      err
      ? failure(err)
      : success(info)
    )
  )
)
</code></pre>
<p>This breaks 1 of the tests because the stub used to be a function; now it needs to be an Object with a function. However&#8230; we should be a little more honest and use a true <code>class</code> in the unit tests to be 100% sure. We&#8217;ll take the old 2 tests:</p>
<pre><code class="javascript">describe('sendEmailSafe when called', ()=&gt; {
    const sendEmailStub = (options, callback) =&gt; callback(undefined, 'info')
    const sendEmailBadStub = (options, callback) =&gt; callback(new Error('dat boom'))
    it('should work with good stubs', ()=&gt; {
        return expect(sendEmailSafe(sendEmailStub, {})).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(sendEmailSafe(sendEmailBadStub, {})).to.be.rejected
    })
})
</code></pre>
<p>And change &#8217;em to:</p>
<pre><code>describe('sendEmailSafe when called', ()=&gt; {
    class TransportStub {
        constructor(mailOptions) {
            this.mailOptions = mailOptions
        }
        sendEmail(options, callback) {
            callback(undefined, 'info')
        }
    }
    class TransportStubBad {
        constructor(mailOptions) {
            this.mailOptions = mailOptions
        }
        sendEmail(options, callback) {
            callback(new Error('dat boom'))
        }
    }
    it('should work with good stubs', ()=&gt; {
        return expect(sendEmailSafe(new TransportStub({}), {})).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(sendEmailSafe(new TransportStubBad({}), {})).to.be.rejected
    })
})
</code></pre>
<p>Notice once you go OOP, things get more verbose. Bleh.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 4</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html</link>
					<comments>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:28:18 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5561</guid>

					<description><![CDATA[Concurrency, Compose, and Coverage Welcome to Part 4 where we show how to do concurrency which is a lot easier to get &#8220;for free&#8221; using pure functions, we compose both async and synchronous functions, we and utilize a test coverage report to where next to focus our refactoring and testing efforts. Contents This is a [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Concurrency, Compose, and Coverage</h1>
<p>Welcome to Part 4 where we show how to do concurrency which is a lot easier to get &#8220;for free&#8221; using pure functions, we compose both async and synchronous functions, we and utilize a test coverage report to where next to focus our refactoring and testing efforts.<br />
<span id="more-5561"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 4.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>Compose Again</h1>
<p>Assuming <code>getUserEmail</code> succeeded, we&#8217;ll have the user&#8217;s information so we can send an email. We now need to read the text email template to inject that information into. We&#8217;ll compose that <code>readFile</code> function we wrote. The existing code is imperatively inside the <code>getUserEmail</code>&#8216;s then:</p>
<pre><code class="javascript">...
userModule.getUserEmail(get('cookie.sessionID', req))
    .then(value =&gt; {
        fs.readFile('./templates/email.html', 'utf-8', (err, template) =&gt; {
            if (err) {
                console.log(err)
                    err.message = 'Cannot read email template'
                    err.httpStatusCode = 500
                    return next(err)
            }
...
</code></pre>
<p>Let&#8217;s fix that and compose them together #connectDemTrainTrax:</p>
<pre><code class="javascript">...
userModule.getUserEmail(get('cookie.sessionID', req))
.then(userInfo =&gt; readEmailTemplate(fs)))
.then(template =&gt; ...)
...
</code></pre>
<p>Great! We even removed all the error handling as that&#8217;s built into our pure <code>readEmailTemplate</code> function.</p>
<h2>Parallelism, Not Concurrency (Who Cares)</h2>
<p>However, that&#8217;s one new problem; we need <code>userInfo</code> later on once we&#8217;ve gotten all the email info setup and ready. Since it&#8217;s only in scope for this function it&#8217;s now gone. One of JavaScript&#8217;s most powerful and taken for granted features, <a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36">closures</a>, we just threw out the window to remain &#8220;pure&#8221; for purity&#8217;s sake.</p>
<p>We can fix it, though, with one of JavaScript&#8217;s other features: <a href="https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/">non-blocking I/O</a>. We can return 3 Promises and wait for all 3 to complete, and use all 3 values in the same function. It doesn&#8217;t matter if one takes longer than the others; <code>Promise.all</code> will wait for all 3 to be done, then give us an Array with all 3 values in order. If even 1 has an error, it&#8217;ll just pop out the <code>.catch</code>. This has 2 bad problems, but we&#8217;ll tackle that in another article. This also has the benefit of being faster in that we don&#8217;t have to wait for each in line, they all happen &#8220;at the same time Node style&#8221; which is not the same as &#8220;happening at the same time <a href="https://blog.codeship.com/comparing-elixir-go/">Elixir/Erlang or Go style</a>&#8221; but that&#8217;s ok, we can get into the same <a href="https://www.youtube.com/watch?v=6scxiuiftKY">dance club</a>.</p>
<p>For now, we&#8217;ll refactor to:</p>
<pre><code class="javascript">...
Promise.all([
      getUserEmail(get('cookie.sessionID', req)),
      readEmailTemplate(readFile),
      mapFilesToAttachments(filterCleanFiles(get('files', req)))
    ])
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; ...)
...
</code></pre>
<p>Now we&#8217;re talking. Loading from an external web service, reading from a local file, and a synchronous function call all can happen &#8220;at the same time&#8221;, and we don&#8217;t have to worry about how long each one takes. We use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Array Destructuring</a> to get our arguments out. Note they come in the same order we put the functions into the <code>Promise.all</code>.</p>
<p>We now have our user&#8217;s email address, the text template to inject information into, along with the file attachments used for both in the same function scope.</p>
<h2>Synchronous Compose</h2>
<p>One thing to nitpick. Sometimes you refactor FP code for readability purposes, not just for the mathematical purity reasons. In this case, check out the 3 levels of nesting:</p>
<pre><code class="javascript">mapFilesToAttachments(filterCleanFiles(get('files', req)))
</code></pre>
<p>In imperative code, if you see if/then statements nested more than 2 levels deep, that tends raise concern. Developers are sometimes fine with creating that code to ensure they truly understand the different cases in playing with ideas, but once complete, they don&#8217;t like LEAVING it that way. Nested if statements are hard to read and follow. If you DO follow them, you can sometimes get a rush or high in &#8220;figuring it out&#8221;. That&#8217;s not the goal, though; nested if&#8217;s are considered bad practice.</p>
<p>For FP, deeply nested functions like this have the same problem. It&#8217;s compounded by the fact we attempted to use verbose names for the functions to make what they do more clear vs. short names. This ends up making the problem worse.</p>
<p>For Promises, it&#8217;s not so bad; you just shove them in the <code>.then</code>. But what about synchronous code?</p>
<p>You have 2 options:</p>
<ol>
<li>Simply wrap in them in a Promise; most promises except for a couple of edge cases are fine getting a return value of a <code>Promise</code> or a value as long as the value isn&#8217;t an <code>Error</code>.</li>
<li>Use Lodash&#8217; <code>flow</code> function, or Ramda&#8217;s <code>compose</code>.</li>
<li>Use the pipeline operator.</li>
</ol>
<p>Sadly, at the time of this writing, the <a href="https://github.com/tc39/proposal-pipeline-operator">pipeline operator</a> is only at Stage 1 for JavaScript, meaning it&#8217;s not even considered a possibility for inclusion in the ECMA Standard yet. None of this code is asynchronous so we&#8217;ll use the Lodash <code>flow</code> (I like Ramda&#8217;s compose name better).</p>
<p>Let&#8217;s put the functions in order, just like we would with a Promise chain:</p>
<pre><code class="javascript">const filterCleanFilesAndMapToAttachments = flow([
  get('files'),
  filterCleanFiles,
  mapFilesToAttachments
])
</code></pre>
<p>Note the use of <code>get('files')</code>. The <code>get</code> function takes 2 arguments, but we only supply 1. We know it&#8217;s curried by default, meaning it&#8217;ll be a partial application if we just say <code>get('files')</code>; it&#8217;s waiting for the 2nd argument. Once it gets that, it&#8217;ll search for the &#8216;files&#8217; property on it, else give <code>undefined</code>. If it DOES find <code>undefined</code>, <code>filterCleanFiles</code> will just spit out an empty Array, and <code>mapFilesToAttachments</code> will spit out an empty Array when you give it an empty Array. Otherwise, they&#8217;ll get the good Array full of files, and both of those functions will do their thang.</p>
<p>See how we use curried functions that create partial applications to help compose other functions? I know&#8230; for you guys, not a good pickup line, but you never know, she me might be a Data Scientist who digs Scala. Or she&#8217;s lit and you look good and anything you say doesn&#8217;t really matter at that point. Either way, it&#8217;s alllll good.</p>
<p>Now to use that composed function, we take what we had:</p>
<pre><code class="javascript">Promise.all([
  getUserEmail(get('cookie.sessionID', req)),
  readEmailTemplate(readFile),
  mapFilesToAttachments(filterCleanFiles(get('files', req)))
])
</code></pre>
<p>And replace it with our composed function:</p>
<pre><code class="javascript">Promise.all([
  getUserEmail(get('cookie.sessionID', req)),
  readEmailTemplate(readFile),
  filterCleanFilesAndMapToAttachments(req)
])
</code></pre>
<p>Much better eh? Speaking of lit, I&#8217;m feeling that hard root beer right now, but I STILL remember we need to unit test our composed function. Let&#8217;s do that&#8230; and with confidence because we already have 3 unit tested pure functions, and we composed them together with a Lodash pure function. DAT CONFIDENCE BUILDING! Also, you MAY have to install config and nodemailer: <code>npm i config nodemailer</code> and then require them up top. Also, depending on the order of functions, you may have to move some functions around giving while we&#8217;re creating pure functions, they&#8217;re defined IN an imperative way, and so order matters. i.e. you have to create the <code>const app = express()</code> first before you can <code>app.post</code>.</p>
<pre><code class="javascript">describe('filterCleanFilesAndMapToAttachments when called', ()=&gt; {
    it('should give an attachment from a request with clean file', ()=&gt;{
        const reqStub = {files: [{scan: 'clean', originalname: 'so fresh', path: '/o/m/g'}]}
        const result = filterCleanFilesAndMapToAttachments(reqStub)
        expect(result[0].filename).to.equal('so fresh')
    })
    it('should give an empty Array with no files', ()=&gt;{
        const reqStub = {files: [{scan: 'dirty south', originalname: 'so fresh', path: '/o/m/g'}]}
        const result = filterCleanFilesAndMapToAttachments(reqStub)
        expect(result).to.be.empty
    })
    it('should give an empty Array with undefined', ()=&gt;{
        const result = filterCleanFilesAndMapToAttachments(undefined)
        expect(result).to.be.empty
    })
})
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM-300x68.png" alt="" width="300" height="68" class="alignleft size-medium wp-image-5524" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM-300x68.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM-768x175.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM.png 780w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>:: chink chunk :: <a href="https://www.youtube.com/watch?v=3ATBJGkdYgI">NIIIIICCCE!</a></p>
<h2>Composing the Promise Way</h2>
<p>You can also just compose the Promise way, and they&#8217;ll work for Promise based functions as well as synchronous ones allowing you to use interchangeably. Let&#8217;s first delete all the no-longer-needed imperative code:</p>
<pre><code class="javascript">let attachments = []
files.map(file =&gt; {
  if (file.scan === 'clean') {
    attachments.push({ filename: file.originalname, path: file.path })
  }
})

value.attachments = attachments
req.attachments = attachments
</code></pre>
<p>And we&#8217;ll take the remaining mix of synchronous and imperative code, and one by one wire together:</p>
<pre><code class="javascript">let emailBody = Mustache.render(template, value)
let emailService = config.get('emailService')
const transporter = nodemailer.createTransport({
  host: emailService.host,
  port: emailService.port,
  secure: false,
})

const mailOptions = {
  from: emailService.from,
  to: emailService.to,
  subject: emailService.subject,
  html: emailBody,
  attachments: attachments,
}

transporter.sendMail(mailOptions, (err, info) =&gt; {
  if (err) {
    err.message = 'Email service unavailable'
    err.httpStatusCode = 500
    return next(err)
  } else {
    return next()
  }
})
</code></pre>
<p>You hopefully are getting trained at this point to start noticing &#8220;globals in my function&#8221;. Note our current line of code is:</p>
<pre><code class="javascript">let emailBody = Mustache.render(template, value)
</code></pre>
<p>But nowhere in the function arguments do we pass the <code>render</code> function to use. Let&#8217;s quickly modify the ever-growing Express route function signature from:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, req, res, next) =&gt;
</code></pre>
<p>to:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
</code></pre>
<p>We&#8217;re already in a Promise at this point, so we can return a value here, or a Promise and we&#8217;ll be sure we can add another <code>.then</code> if we need to. One trick <a href="https://code.visualstudio.com/">VSCode</a>, a free text and code editor by Microsoft, has is highlighting variables. Before we shove this rendered email template variable in the Monad train, let&#8217;s see if anyone down the tracks needs it. We&#8217;ll select the whole variable, and watch how VSCode will highlight usage of it as well:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.26.52-PM.png" alt="" width="652" height="780" class="alignleft size-full wp-image-5525" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.26.52-PM.png 652w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.26.52-PM-251x300.png 251w" sizes="auto, (max-width: 652px) 100vw, 652px" /></p>
<p>Crud&#8230; it&#8217;s a ways down, AND it&#8217;s mixed in with this <code>emailService</code> thing. Let&#8217;s highlight him and see where he&#8217;s grouped:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.28.56-PM.png" alt="" width="656" height="778" class="alignleft size-full wp-image-5526" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.28.56-PM.png 656w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.28.56-PM-253x300.png 253w" sizes="auto, (max-width: 656px) 100vw, 656px" /></p>
<p>This&#8217;ll be tricky. Good news, rendering the email and loading the email service configuration can be done at the same time. Let&#8217;s keep that INSIDE the Promise now until we feel comfortable we no longer need the <code>userEmailAddress</code>, <code>emailTemplate</code>, <code>fileAttachments</code> in scope. A lot more pragmatic people would be fine with keeping the code this way, and using JavaScript&#8217;s built in feature of closures, and move on with life. However, imperative code is harder to test, and results in LONGER code vs. smaller, pure functions that are easier to test. You don&#8217;t always START there, though. It&#8217;s fine to write imperative, then write &#8220;kind of pure&#8221; and keep refactoring your way there. That&#8217;s part of learning, figuring our the idea of how your code should work, or both.</p>
<pre><code class="javascript">...
.then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; {
    return Promise.all([
      render(render, template, userEmailAddress),
      getEmailService(config)
    ])
    .then( ([emailBody, emailService]) =&gt; ...
...
</code></pre>
<p>And we&#8217;ll clean up the code below to use our pure functions first imperatively:</p>
<pre><code class="javascript">...
.then( ([emailBody, emailService]) =&gt; {
  const transportObject = createTransportObject(emailService.host, emailBody.port)
  const transport = createTransport(transportObject)
  const sendEmailFunction = transport.sendEmail
  const mailOptions = createMailOptions(
    emailService.from,
    emailService.to,
    emailService.subject,
    emailBody,
    fileAttachments
  )
  return sendEmailSafe(sendEmailFunction, mailOptions)
})
</code></pre>
<p>&#8230; and then refactor to more functional:</p>
<pre><code class="javascript">...
.then( ([emailBody, emailService]) =&gt;
  sendEmailSafe(
    createTransport(
      createTransportObject(emailService.host, emailBody.port)
    ).sendEmail,
    createMailOptions(
      emailService.from,
      emailService.to,
      emailService.subject,
      emailBody,
      fileAttachments
    )
  )
})
...
</code></pre>
<p>Note the <code>fileAttachments</code> comes from the scope higher up. The <code>sendEmailSafe</code> function requires a nodemailer <code>transport</code>. We create that from our function that creates the Object from the <code>emailService</code>. Once created we need that <code>sendEmail</code> function to pass it to the <code>sendEmailSafe</code> so we just immediately go <code>.sendEmail</code> in the first parameter. The <code>createMailOptions</code> is another function that simply creates our Object from the <code>emailService</code> object, the rendered via Mustache <code>emailBody</code>, and the virus scanned <code>fileAttachements</code>. One last touch is to remove the squiggly braces <code>{}</code> as we&#8217;re no longer writing imperative code, and the <code>return</code> statement as Arrow functions have an implicit return when you remove the squiggly braces.</p>
<p>This last part is left over from the callback:</p>
<pre><code class="javascript">), reason =&gt; {
      return next(reason)
    })
</code></pre>
<p>Typically you defer <code>Promise</code> error handling higher up the call stack; meaning, &#8220;let whoever is calling me deal with error handling since Promises that call Promises have their errors propagate up&#8221;. That&#8217;s fine, so&#8230; we&#8217;ll delete it.</p>
<p>After all that refactoring, here&#8217;s what we&#8217;re left with:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
    Promise.all([
      getUserEmail(get('cookie.sessionID', req)),
      readEmailTemplate(readFile),
      filterCleanFilesAndMapToAttachments(req)
    ])
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; 
      Promise.all([
          render(render, template, userEmailAddress),
          getEmailService(config)
        ])
        .then( ([emailBody, emailService]) =&gt;
          sendEmailSafe(
            createTransport(
              createTransportObject(emailService.host, emailBody.port)
            ).sendEmail,
            createMailOptions(
              emailService.from,
              emailService.to,
              emailService.subject,
              emailBody,
              fileAttachments
            )
          )
        )
    ))
</code></pre>
<h1>Coverage Report</h1>
<p>Let&#8217;s unit test it; it&#8217;ll be hard because we have a lot of stubs, but we can borrow from the ones we&#8217;ve already created in the other tests. I&#8217;m not going to DRY the code at all in the tests as that would require too much brainpower at this point, but when you get an Agile Sprint or time to pay down technical debt, this is one of the stories/tasks you add to that list.</p>
<p>&#8230; before we do, let&#8217;s run a coverage report to see how much work we have cut out for us (we&#8217;re ignoring my fake npm module and the user stuff for now). Run <code>npm run coverage &amp;&amp; open coverage/lcov-report/index.html</code>:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-1024x79.png" alt="" width="525" height="41" class="alignleft size-large wp-image-5530" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-1024x79.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-300x23.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-768x59.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM.png 1950w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>And the details around our particular function:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-1024x600.png" alt="" width="525" height="308" class="alignleft size-large wp-image-5531" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-1024x600.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-300x176.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-768x450.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM.png 1462w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<h2>Status Quo at This Point</h2>
<p>Wonderful; the only thing we need to test is the composition of those functions in <code>Promise.all</code>. Rather than create 20 billion stubs, and ensure they&#8217;re setup &#8220;just so&#8221; so the <code>sendEmail</code> unit test passes or fails, we&#8217;ll continue to our strategy of pulling out teency pieces, wrapping them in pure functions, testing those, repeat. Let&#8217;s start with the first <code>Promise.all</code>:</p>
<pre><code class="javascript">const getSessionIDFromRequest = get('cookie.sessionID')
const getEmailTemplateAndAttachments = curry((getUserEmail, readFile, req) =&gt;
  Promise.all([
    getUserEmail(getSessionIDFromRequest(req)),
    readEmailTemplate(readFile),
    filterCleanFilesAndMapToAttachments(req)
  ]))
</code></pre>
<p>Then we&#8217;ll unit test the <code>getEmailTemplateAndAttachments</code> (he&#8217;ll end up ensuring we&#8217;ve tested the new <code>getSessionIDFromRequest</code>):</p>
<pre><code class="javascript">describe('getEmailTemplateAndAttachments when called', ()=&gt; {
    const reqStub = {
        cookie: { sessionID: '1' },
        files: [{scan: 'clean', originalname: 'so fresh', path: '/o/m/g'}]
    }
    const getUserEmailStub = () =&gt; 'email'
    const readFileStub = (path, encoding, callback) =&gt; callback(undefined, 'email')
    const readFileStubBad = (path, encoding, callback) =&gt; callback(new Error('b00mz'))
    it('should succeed with good stubs', ()=&gt; {
        return expect(
            getEmailTemplateAndAttachments(getUserEmailStub, readFileStub, reqStub)
        ).to.be.fulfilled
    })
    it('should succeed resolve to having an email', ()=&gt; {
        return getEmailTemplateAndAttachments(getUserEmailStub, readFileStub, reqStub)
        .then( ([userEmail, emailBody, attachments]) =&gt; {
            expect(userEmail).to.equal('email')
        })
    })
    it('should fail if reading file fails', ()=&gt; {
        return expect(
            getEmailTemplateAndAttachments(getUserEmailStub, readFileStubBad, reqStub)
        ).to.be.rejected
    })
})
</code></pre>
<p>And we&#8217;ll then swap it out for the raw <code>Promise.all</code>:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
    getEmailTemplateAndAttachments(getUserEmail, readFile, req)
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; 
      Promise.all([
          render(render, template, userEmailAddress),
          getEmailService(config)
        ])
        .then( ([emailBody, emailService]) =&gt;
          sendEmailSafe(
            createTransport(
              createTransportObject(emailService.host, emailBody.port)
            ).sendEmail,
            createMailOptions(
              emailService.from,
              emailService.to,
              emailService.subject,
              emailBody,
              fileAttachments
            )
          )
        )
    ))
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.58.21-AM.png" alt="" width="622" height="184" class="alignleft size-full wp-image-5532" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.58.21-AM.png 622w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.58.21-AM-300x89.png 300w" sizes="auto, (max-width: 622px) 100vw, 622px" /></p>
<p>&#8230; and then re-run coverage. Just run <code>npm run coverage</code> and you can refresh the coverage in the browser:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-1024x504.png" alt="" width="525" height="258" class="alignleft size-large wp-image-5533" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-1024x504.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-300x148.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-768x378.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM.png 1466w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>As you can see, coverage isn&#8217;t going to let us off that easy. That&#8217;s ok, we can re-use these stubs for the final battle. Let&#8217;s do the last <code>Promise.all</code>.</p>
<pre><code class="javascript">describe('renderEmailAndGetEmailService when called', ()=&gt; {
    const configStub = { has: stubTrue, get: () =&gt; 'email service' }
    const renderStub = stubTrue
    const renderStubBad = () =&gt; { throw new Error('intentionally failed render')}
    it('should work with good stubs', ()=&gt; {
        return expect(
            renderEmailAndGetEmailService(configStub, renderStub, 'template', 'user email')
        ).to.be.fulfilled
    })
    it('should resolve to an email', ()=&gt; {
        return renderEmailAndGetEmailService(configStub, renderStub, 'template', 'user email')
        .then( ([emailRendered, emailService]) =&gt; {
            expect(emailRendered).to.equal(true)
        })
    })
    it('should fail if rendering fails', ()=&gt; {
        return expect(
            renderEmailAndGetEmailService(configStub, renderStubBad, 'template', 'user email')
        ).to.be.rejected
    })
})
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.20.15-AM.png" alt="" width="572" height="184" class="alignleft size-full wp-image-5534" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.20.15-AM.png 572w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.20.15-AM-300x97.png 300w" sizes="auto, (max-width: 572px) 100vw, 572px" /></p>
<p>And swap it out:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
    getEmailTemplateAndAttachments(getUserEmail, readFile, req)
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; 
      renderEmailAndGetEmailService(config, render, emailTemplate, userEmailAddress)
      .then( ([emailBody, emailService]) =&gt;
        sendEmailSafe(
          createTransport(
            createTransportObject(emailService.host, emailBody.port)
          ).sendEmail,
          createMailOptions(
            emailService.from,
            emailService.to,
            emailService.subject,
            emailBody,
            fileAttachments
          )
        )
      )
    ))
</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 3</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:27:52 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5559</guid>

					<description><![CDATA[OOP, Compose, and Curry Welcome to Part 3 where we&#8217;ll show you how to navigate class based code using FP, go over composing all these asynchronous functions we wrote, and continuing to define our dependencies in curried functions to make them easier to test. Contents This is a 6 part series on refactoring imperative code [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>OOP, Compose, and Curry</h1>
<p>Welcome to Part 3 where we&#8217;ll show you how to navigate <code>class</code> based code using FP, go over composing all these asynchronous functions we wrote, and continuing to define our dependencies in curried functions to make them easier to test.<br />
<span id="more-5559"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 3.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>Class Wrangling</h1>
<p>The use of <a href="https://nodemailer.com/about/">nodemailer</a> is tricky. It&#8217;s a library that sends emails in Node. However, it uses a lot of classes and instances to do so which makes even just stubbing a pain, but we&#8217;ll make it work. We&#8217;ll tackle the Object creation stuff first since factory functions, functions that simply return an Object based on input data, are easier to write, compose, and test.</p>
<h2>Simple Object Creation First</h2>
<p>For this transport object:</p>
<pre><code class="javascript">const transporter = nodemailer.createTransport({
    host: emailService.host,
    port: emailService.port,
    secure: false,
})
</code></pre>
<p>We&#8217;ll take out the Object part, and just create that as a pure factory function:</p>
<pre><code class="javascript">const createTransportObject = (host, port) =&gt; ({
  host,
  port,
  secure: false,
})
</code></pre>
<p>And then test:</p>
<pre><code class="javascript">describe('createTransport when called', ()=&gt; {
    it('should create a host', ()=&gt; {
        expect(createTransportObject('host', 'port').host).to.equal('host')
    })
    it('should crate a port', ()=&gt; {
        expect(createTransportObject('host', 'port').port).to.equal('port')
    })
})
</code></pre>
<p>Next up, the mailOptions Object:</p>
<pre><code class="javascript">const mailOptions = {
  from: emailService.from,
  to: emailService.to,
  subject: emailService.subject,
  html: emailBody,
  attachments: attachments,
}
</code></pre>
<p>We&#8217;ll just convert to a function:</p>
<pre><code class="javascript">const createMailOptions = (from, to, subject, html, attachments) =&gt;
({
  from,
  to,
  subject,
  html,
  attachments
})
</code></pre>
<p>And do a single test because I&#8217;m at the pool with my girls and lazy right meowwww, omg dat sun is amaze:</p>
<pre><code class="javascript">describe('createMailOptions when called', ()=&gt; {
    it('should create an Object with from', ()=&gt; {
        expect(createMailOptions('from', 'to', 'subject', 'html', []).from)
        .to.equal('from')
    })
})
</code></pre>
<p>Last one is the error. We&#8217;ll take this:</p>
<pre><code class="javascript">...
if (err) {
  err.message = 'Email service unavailable'
  err.httpStatus
    ...
</code></pre>
<p>And convert to another factory function:</p>
<pre><code class="javascript">const getEmailServiceUnavailableError = () =&gt; new Error('Email service unavailable')
</code></pre>
<p>And the test:</p>
<pre><code class="javascript">describe('getEmailServiceUnavailableError when called', ()=&gt; {
    it('should create an error with a message', ()=&gt; {
        const error = getEmailServiceUnavailableError()
        expect(error.message).to.equal('Email service unavailable')
    })
})
</code></pre>
<p>Routine by now, right? Give some inputs, test the output, stub if you need to. Eventually these functions can be combined together either synchronously or asynchronously.</p>
<h2>Dem Crazy Classes</h2>
<p>Now it&#8217;s time to wrap the nodemailer class creation. We&#8217;ll take the <code>createTransport</code>:</p>
<pre><code class="javascript">const transporter = nodemailer.createTransport({
  host: emailService.host,
  port: emailService.port,
  secure: false,
})
</code></pre>
<p>and make it pure (we already took out the transport object creation):</p>
<pre><code class="javascript">const createTransportMailer = curry((createTransportFunction, transportObject) =&gt;
  createTransportFunction(transportObject))
</code></pre>
<p>And the test:</p>
<pre><code class="javascript">describe('createTransportMailer when called', ()=&gt; {
    it('should work with good stubs', ()=&gt; {
        expect(createTransportMailer(stubTrue, {})).to.equal(true)
    })
})
</code></pre>
<p>Not so bad. Now let&#8217;s tackle the actual send email. We&#8217;ll take the existing callback:</p>
<pre><code class="javascript">transporter.sendMail(mailOptions, (err, info) =&gt; {
  if (err) {
    err.message = 'Email service unavailable'
    err.httpStatusCode = 500
    return next(err)
  } else {
    return next()
  }
})
</code></pre>
<p>And remove the next, and convert to a pure Promise based function:</p>
<pre><code class="javascript">const sendEmailSafe = curry((sendEmailFunction, mailOptions) =&gt;
  new Promise((success, failure) =&gt;
    sendEmailFunction(mailOptions, (err, info) =&gt;
      err
      ? failure(err)
      : success(info)
    )
  )
)
</code></pre>
<p>As before, you pass the actual function that sends the email and we&#8217;ll call it. This allows your real code to pass in the nodemailer&#8217;s <code>transport.sendEmail</code>, and unit tests a simple function.</p>
<pre><code class="javascript">describe('sendEmailSafe when called', ()=&gt; {
    const sendEmailStub = (options, callback) =&gt; callback(undefined, 'info')
    const sendEmailBadStub = (options, callback) =&gt; callback(new Error('dat boom'))
    it('should work with good stubs', ()=&gt; {
        return expect(sendEmailSafe(sendEmailStub, {})).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(sendEmailSafe(sendEmailBadStub, {})).to.be.rejected
    })
})
</code></pre>
<p>How we lookin&#8217;?</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-11-at-7.06.57-PM-173x300.png" alt="" width="173" height="300" class="alignleft size-medium wp-image-5519" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-11-at-7.06.57-PM-173x300.png 173w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-11-at-7.06.57-PM-591x1024.png 591w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-11-at-7.06.57-PM.png 740w" sizes="auto, (max-width: 173px) 100vw, 173px" /></p>
<p>Supa-fly. Let&#8217;s keep going.</p>
<h1>Compose in Dem Rows</h1>
<p>Now that we have tested functions, we can start composing them together. However, that&#8217;d kind of defeats the purpose of &#8220;refactoring a moving target&#8221; which is what&#8217;s helpful to more people.</p>
<p>Meaning, often you&#8217;ll work on codebases that you didn&#8217;t create, or you did, but you&#8217;re still struggling to keep all the moving pieces in your head as requirements change. How can you positively affect them without changing too much of the interfaces? It&#8217;s a skill that&#8217;s learned with practice.</p>
<p>So let&#8217;s practice together! We&#8217;ve already looked at the function, identified the pieces that need to be pure, visualized (sort of) how they fit together an an imperative-like order, and unit tested them (mostly) thoroughly.</p>
<h2>Peace Out Scope</h2>
<p>Let&#8217;s tidy the place up first. This:</p>
<pre><code class="javascript">function sendEmail(req, res, next) {
</code></pre>
<p>to this to ensure no need for <code>this</code>:</p>
<pre><code class="javascript">const sendEmail = (req, res, next) =&gt; {
</code></pre>
<p>We&#8217;ll nuke that <code>{</code> into orbit when we&#8217;re done, for now he can chill.</p>
<h2>Saferoom</h2>
<p>The rule for JavaScript is that as soon as something is async; meaning your function/closure uses a callback or Promise, everything is async. The Promise is flexible in that you can return a value or a Promise and the rest of the <code>.then</code> and <code>.catch</code> will work.</p>
<p>One feature that the FP developers love is that it has built-in <code>try/catch</code>.</p>
<pre><code class="javascript">const backup = () =&gt; new Promise( success =&gt; {
    console.log("hey, about to boom")
    throw new Error('boom')
})

backup()
.then(() =&gt; console.log("won't ever log"))
.catch(error =&gt; console.log("it boomed:", error))
</code></pre>
<p>The bad news is that SOMEONE has to <code>.catch</code> or you&#8217;ll get an uncaught exception. In Node that&#8217;s the <a href="https://nodejs.org/api/process.html#process_event_unhandledrejection">unhandledRejection event</a>, and in the browser the <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onunhandledrejection">window.onunhandledrejection event</a>. Worse, a lot of <code>async/await</code> examples exclude the try/catch, completely ignoring that errors can happen, accidentally encouraging impure, error prone functions.</p>
<p>Eventually you&#8217;ll want to look into never allowing a Promise to throw/catch, and instead return an ADT. You can <a href="http://jessewarden.com/2017/11/error-handling-strategies.html">read more</a> about doing that with a <a href="https://www.youtube.com/watch?v=0iiZHlT0boc">video example using async/await</a> as well.</p>
<h2>Start With A Promise</h2>
<p>We fixed the function to be an <a href="https://www.youtube.com/watch?v=oLDRQtFx72M">arrow function</a> to remove any care about scope and <code>this</code>. The function has inputs. What it is missing is an output. You&#8217;ll notice they return <code>next</code>, but the <code>next</code> function is a <a href="https://lodash.com/docs/4.17.10#noop">noop</a>, a method that returns <code>undefined</code>. It doesn&#8217;t return any value and is considered a &#8220;no operation&#8221;, which we also call &#8220;something that intentionally creates side effects&#8221;, similar to <code>console.log</code>. In console&#8217;s case, it shoves text in standard out.</p>
<p>Since it&#8217;s an async function, let&#8217;s return a Promise, and gain the error handling benefits as well. We&#8217;ll change the signature from this:</p>
<pre><code class="javascript">const sendEmail = (req, res, next) =&gt; {
  const files = req.files
  ...
</code></pre>
<p>To this:</p>
<pre><code class="javascript">const sendEmail = (req, res, next) =&gt; {
  return new Promise((success, failure) =&gt; {
    const files = req.files
        ...
</code></pre>
<p>Don&#8217;t worry, we&#8217;ll get rid of the <code>return</code> and the second <code>{</code> later on. The good news at this point is we could unit test <code>sendEmail</code> in a functional way by giving it some inputs, and checking what it outputs. The first test would output a Promise. The second would output to <code>undefined</code> for now because of <code>next</code>.</p>
<h1>Define Your Dependencies</h1>
<p>However, as you can see we still need a lot of mocks because none of the 4 dependencies like <code>userModule.getUserEmail</code>, <code>fs.readFile</code>, <code>config.get</code>, and <code>nodemailer.createTransport</code> are an input to the function. Let&#8217;s remove the need for mocks right meow.</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, req, res, next) =&gt; 
...
</code></pre>
<p>Now you know the dark secret of Unix and Functional Programming: &#8220;It&#8217;s someone else&#8217; problem to deal with state/supplying dependencies higher up the chain.&#8221; We&#8217;re high up the chain, it&#8217;s our responsibility, and suddenly FP doesn&#8217;t feel so off the chain, eh?</p>
<h1>Currying Options</h1>
<p>Before we talk about how to make this easier to deal with, let&#8217;s talk about the order of the parameters which is intentional to make currying more useful. This is also my opinion around order, so feel free change the order as you see fit.</p>
<p>You DO NOT have to use curry or use partial applications. It&#8217;s just useful in functional programming because you&#8217;ll often have a lot of parameters like this where many of them are known ahead of times, so you just make it a habit. It can also help reduce the verbosity in using pure functions and your unit tests. It also makes composing easier because sometimes you&#8217;ll already know a few of the parameters ahead of time.</p>
<h2>Left: Most Known/Common, Right: Less Known/Dynamic</h2>
<p>The overall goal with curried functions is put the most known ahead of time dependencies to the left, and the most unknown things to the right.</p>
<p>Reading files in Node via <code>fs</code> is commonly known since it&#8217;s built into Node. So that&#8217;s first.</p>
<p>The <a href="https://github.com/lorenwest/node-config">config</a> library in Node is a common library often at the core of how your app handles different environments and configurations. So that&#8217;s a tight second.</p>
<p>The nodemailer&#8217;s <code>createTransport</code> function is 3rd since there aren&#8217;t that many options to send emails in Node, but it&#8217;s still a library unlike <code>fs</code>.</p>
<p>The <code>getUserEmail</code> is our function that accesses a 3rd party service that gets the user information so we can get their email address. We snag this from their session ID. This is not a well known library, nor a built in function to Node, it&#8217;s something we built ourself and could change, so it&#8217;s 4th.</p>
<p>The <code>req</code> is the Express Request object, the <code>res</code> if the Express Response object, and the <code>next</code> is the connect middleware function.</p>
<p>Hopefully your Spidey Sense is tingling, and you immediately say to yourself, &#8220;Wait a minute, this is an <a href="https://expressjs.com/">Express</a> application, the req/res/next parameters are super well known; why aren&#8217;t they first, or at least 3rd?&#8221; The answer is yes and no.</p>
<p>Yes, this function is currently an Express middleware function, and is expected to have 1 of the 2 signatures: <code>(req, res, next)</code> for middleware, and <code>(err, req, res, next)</code> for error handlers.</p>
<p>No, in that we&#8217;d never give a function to an Express route without concrete implementations. Meaning, we don&#8217;t expect Express to somehow magically know we need a <code>config</code>, <code>nodemailer</code>, etc. We&#8217;ll give those, like this:</p>
<pre><code class="javascript">app.post('/upload', sendEmail(fs.readFile, config, nodemailer.createTransport, user.getUserEmail))
</code></pre>
<p>And now you see why; the Express request, response, and next function are actually the most dynamic parts. We won&#8217;t know those until the user actually attempts to upload a file, and Express gives us the request, response, and next function. We just supply the first 4 since we know those.</p>
<p><strong>WARNING</strong>: Beware putting curried functions into middlewares. Express checks the function arity, how many arguments a function takes, to determine which type of middleware it should make: 3 for middleware, 4 for an error handler. They check function arity via <code>Function.length</code>. Lodash&#8217;s curried functions always report 0. Sanctuary always reports 1 because of their &#8220;functions should only ever take 1 parameter&#8221; enforcement. Ramda is the only one that retains function arity. Since Express only cares about errors, you&#8217;re safe putting <code>(req, res, next)</code> middlewares with a 0 or 1 function arity. For errors, you&#8217;ll have to supply old school functions, or a wrapper that has default parameters that default to concrete implementations.</p>
<p>Knowing the limitations, we&#8217;ll be fine, so let&#8217;s use Lodash&#8217; <a href="https://lodash.com/docs/4.17.10#curry">curry</a>.</p>
<h1>Start The Monad Train&#8230; Not Yet</h1>
<p>Let&#8217;s start the Promise chain by validating the files. However, that pesky <code>next</code> function adds a wrinkle:</p>
<pre><code class="javascript">const files = req.files
    if (!Array.isArray(files) || !files.length) {
      return next()
    }
</code></pre>
<p>The entire function needs to be aborted if there are no files to email. Typically Promises, or Eithers, operate in a Left/Right fashion. A Promise says, &#8220;If everything&#8217;s ok, we keep calling thens. If not, we abort all thens and go straight to the catch&#8221;. An Either works about the same way; &#8220;If everything is ok, we return a Right. If not, we return an Left bypassing all Rights we find.&#8221; This is because like Promises, you can chain Eithers.</p>
<p>However, there&#8217;s no way to &#8220;abort early&#8221;. If you go back to an <code>async/await</code> style function, you can write it imperative style and abort early. We&#8217;re not in the business of creating imperative code, though. For now, we&#8217;ll just use a simple ternary if to determine if we should even go down the email route.</p>
<pre><code class="javascript">const sendEmailOrNext = curry((readFile, config, createTransport, getUserEmail, req, res, next) =&gt;
  validFilesOnRequest(req)
    ? sendEmail(readFile, config, createTransport, getUserEmail, req, res, next)
    : next() &amp;&amp; Promise.resolve(false))
</code></pre>
<p>Note 2 important things here. We only run the <code>sendEmail</code> function if we even have files to process. Second, since <code>next</code> is a noop, we can ensure the <code>Promise.resolve(false)</code> will return the resolved Promise with the resolved in it. This allows the next to inform Express that this middleware has completed successfully, AND return a meaningful value; <code>false</code> for not sending the email.</p>
<h2>Ok, NOW Start the Monad Train</h2>
<p>We can now nuke the Array checking. From this:</p>
<pre><code class="javascript">...
return new Promise((success, failure) =&gt; {
    const files = req.files
    if (!Array.isArray(files) || !files.length) {
      return next()
    }
    userModule.getUserEmail(req.cookies.sessionID).then(value =&gt; {
...
</code></pre>
<p>To this:</p>
<pre><code class="javascript">...
return new Promise((success, failure) =&gt; {
    return userModule.getUserEmail(req.cookies.sessionID).then(value =&gt; {
...
</code></pre>
<p>Great, but notice we have now a Promise wrapped in a Promise. Let&#8217;s refactor now that we&#8217;re clear. From this:</p>
<pre><code class="javascript">const sendEmail = curry(readFile, config, createTransport, getUserEmail, req, res, next) =&gt; {
  return new Promise((success, failure) =&gt; {
    return userModule.getUserEmail(req.cookies.sessionID).then(value =&gt; {
</code></pre>
<p>To:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, req, res, next) =&gt;
    userModule.getUserEmail(req.cookies.sessionID).then(value =&gt; {
</code></pre>
<p><a href="https://www.youtube.com/watch?v=t6twhXA1Gyw">Get Busy Child</a>!</p>
<h2>Dem Gets</h2>
<p>One problem, though, with the accessing of the cookie. Express using the <a href="https://github.com/expressjs/cookie-parser">cookie middleware plugin</a> is the one who adds the <code>.cookies</code> Object to the request object. Even so, the cookie might not have been sent from the client. Worse, it&#8217;s a &#8220;dot dot&#8221;. Yes, we &#8220;know&#8221; <code>req</code> here is fine, and yes know &#8220;know&#8221; <code>req.cookies</code> is fine because we imported the module and told Express to use the middleware.</p>
<p>That&#8217;s not the point. We&#8217;re creating pure functions, and <code>getUserEmail</code> is the one whose responsibility is to validate the cookie value. If you can prevent creating null pointers, you&#8217;re well on your way.</p>
<p>Hopefully at this point, again, your Spidey Sense is tingling in wondering why don&#8217;t you first validate the cookie&#8217;s value before you even run this. You should, and if you did, you&#8217;d be well on your way to creating a total function that can handle the variety of types and data, or lack thereof. A <code>Maybe</code> would be better because we&#8217;d be forced to deal with receiving a <code>Nothing</code>. We&#8217;ll keep this pragmatic, and assume another function will handle informing the client that they are missing a sessionID cookie. However, we&#8217;re certainly not going to allow that to negatively affect our functions purity.</p>
<p>For now, just a simple get to make it safe.</p>
<pre><code class="javascript">userModule.getUserEmail(get('cookies.sessionID', req).then(value =&gt; {
</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 2</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:27:13 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5557</guid>

					<description><![CDATA[Predicates, Async, and Unsafe In part 2, we&#8217;ll validate our inputs using predicates, show how to make asynchronous pure functions, and show various techniques on how you call unsafe code from Functional Code. Contents This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Predicates, Async, and Unsafe</h1>
<p>In part 2, we&#8217;ll validate our inputs using predicates, show how to make asynchronous pure functions, and show various techniques on how you call unsafe code from Functional Code.</p>
<p><span id="more-5557"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 2.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h2>Quick History About Middleware</h2>
<p>A middleware is the name for &#8220;a function that takes 2 or 3 arguments, namely req, res, or req, res, and next. In Express, Restify, and Hapi, <code>req</code> is a Request, and represents what the client sent to the server in a request (GET, POST, etc). That is where you inspect whatever form data or JSON or XML they sent to your API. The <code>res</code> is the Response, and typically what you use to respond back to the client via <code>res.send</code>. The <code>next</code> function is optional, and it&#8217;s how the whole <a href="https://github.com/senchalabs/connect">connect middleware</a> concept works.</p>
<p>Before <code>Promise</code> chains were commonplace, there was no defined way to connect up a bunch of functions and have an escape hatch for errors. Promises do that now using 50 billion <code>.then</code> functions, and 1 <code>.catch</code> for errors that happen anywhere in the chain. Instead of calling <code>.then</code> or <code>.catch</code> like you do in Promises, instead, your function agrees to call <code>next()</code> when you&#8217;re done, or <code>next(error)</code> when you have an error, and connect will handle error propagation.</p>
<h2>File Validation</h2>
<p>The first thing we have to refactor in <code>sendEmail</code> is the validation of the files array being on Request.</p>
<pre><code class="javascript">function sendEmail(req, res, next) {
    const files = req.files
    if (!Array.isArray(files) || !files.length) {
        return next()
    }
    ...
</code></pre>
<p>First, let&#8217;s add some predicates that are easier to compose (i.e. use together) and easier to unit test independently.</p>
<pre><code class="javascript">const legitFiles = files =&gt; Array.isArray(files) &amp;&amp; files.length &gt; 0
</code></pre>
<p>A predicate is a function that returns <code>true</code> or <code>false</code>. This as opposed to one that returns <code>true</code>, <code>false</code>, <code>undefined</code>, <code>null</code>, <code>NaN</code>, or &#8221;&#8230; or even throws an Error. Making true predicates in JavaScript usually requires it to be a total function; a pure function that doesn&#8217;t care what types you throw at it. Note we check if it&#8217;s an Array first, and if it is, we can confidently access the <code>.length</code> property. Except, you can&#8217;t. Remember, libraries will still override the <code>Object.prototype</code> of various built-in classes, so using <code>get('length', files)</code> would be a safer option here.</p>
<pre><code class="javascript">describe('legitFiles when called', ()=&gt; {
    it('should work with an Array of 1', ()=&gt; {
        expect(legitFiles(['cow'])).to.be.true
    })
    it('should fail with an Array of 0', ()=&gt; {
        expect(legitFiles([])).to.be.false
    })
    it('should fail with popcorn', ()=&gt; {
        expect(legitFiles('&amp;#x1f37f;')).to.be.false
    })
})
</code></pre>
<p>Note this function is a prime candidate for property testing using <a href="https://github.com/jsverify/jsverify">jsverify</a> for example. Property tests throw 100 random values at your function vs. you creating those yourself. John Hughes who created the inspiration, Quickcheck, <a href="https://www.youtube.com/watch?v=hXnS_Xjwk2Y">has a good YouTube video</a> explaining the rationale.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/hXnS_Xjwk2Y" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>Now that we can verify what a legit files Array looks like, let&#8217;s ensure the request has them:</p>
<pre><code class="javascript">const validFilesOnRequest = req =&gt; legitFiles(get('files', req))
</code></pre>
<p>And to test, we just give either an Object with an files Array property, or anything else to make it fail:</p>
<pre><code class="javascript">describe('validFilesOnRequest when called', ()=&gt; {
    it('should work with valid files on request', ()=&gt; {
        expect(validFilesOnRequest({files: ['cow']})).to.be.true
    })
    it('should fail with empty files', ()=&gt; {
        expect(validFilesOnRequest({files: []})).to.be.false
    })
    it('should fail with no files', ()=&gt; {
        expect(validFilesOnRequest({})).to.be.false
    })
    it('should fail with piggy', ()=&gt; {
        expect(validFilesOnRequest('&amp;#x1f437;')).to.be.false
    })
})
</code></pre>
<p>Ok, we&#8217;re well on our way now to building up some quality functions to refactor the beast route.</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-10.06.36-AM-300x230.png" alt="" width="300" height="230" class="alignleft size-medium wp-image-5509" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-10.06.36-AM-300x230.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-10.06.36-AM.png 692w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<h1>Asynchronous Functions</h1>
<p>With file validation behind us, let&#8217;s tackle the part in the middle that assembles the email. A lot of imperative code in here requiring various mocks and stubs to ensure that part of the code is covered. Instead, we&#8217;ll create pure functions for each part, test independently, then wire together later.</p>
<p>We&#8217;ll hit the <code>fs.readFile</code> first. Callbacks are not pure functions; they are noops, functions that return <code>undefined</code>, but typically intentionally have side effects. Whether you use Node&#8217;s built in <a href="https://nodejs.org/api/util.html#util_util_promisify_original">promisify</a> or wrap it yourself is up to you. We&#8217;ll do it manually to show you how.</p>
<pre><code class="javascript">const readEmailTemplate = fs =&gt;
  new Promise((success, failure) =&gt;
    fs.readFile('./templates/email.html', 'utf-8', (err, template) =&gt;
      err
      ? failure(err)
      : success(template)))
</code></pre>
<p>The only true impurity was <code>fs</code> being a global <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures">closure</a>. Now, it&#8217;s a required function parameter. Given this an asynchronous function, let&#8217;s install <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures">chai-as-promised</a> to give us some nice functions to test promises with via <code>npm i chai-as-promised --save-dev</code>.</p>
<p>Let&#8217;s refactor the top of our unit test a bit to import the new test library:</p>
<pre><code class="javascript">const chai = require('chai')
const { expect } = chai
const chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised)
</code></pre>
<p>Now chai will have new assertion functions we can use to test async functions.</p>
<pre><code class="javascript">describe('readEmailTemplate when called', ()=&gt; {
    const fsStub = {
        readFile: (path, encoding, callback) =&gt; callback(undefined, 'email')
    }
    const fsStubBad = {
        readFile: (path, encoding, callback) =&gt; callback(new Error('b00mz'))
    }
    it('should read an email template file with good stubs', ()=&gt; {
        return readEmailTemplate(fsStub)
    })
    it('should read an email template called email', ()=&gt; {
        return expect(readEmailTemplate(fsStub)).to.become('email')
    })
    it('should fail if fails to read', ()=&gt; {
        return expect(readEmailTemplate(fsStubBad)).to.be.rejected
    })
})
</code></pre>
<p>How bangin&#8217;? Sttraiiiggghhttt bangin&#8217;. Note 2 simple stubs are required; one for an <code>fs</code> that successfully reads a file, and <code>fs</code> that fails. Note they aren&#8217;t mocks because we don&#8217;t care how they were used, what parameters were sent to them, how many times they were called, etc. We just do the bare minimum to get a test to pass.</p>
<h1>Factory Errors</h1>
<p>With the exception of <code>Maybe</code>, we&#8217;ll avoid using union types for now, and instead stick with Promises to know if a function worked or not, regardless if it&#8217;s async or sync. I encourage you to read <a href="http://folktale.origamitower.com/api/v2.1.0/en/folktale.adt.union.union.union.html">Folktale&#8217;s union type&#8217;s documentation</a> on your own time and perhaps <a href="https://youtu.be/OghJR3BP0Ns?t=26m55s">watch my video on Folktale</a> and skip to 22:55.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/OghJR3BP0Ns?start=1615" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>If the server fails to read the email template, we have a specific error for that so the client knows what happened. Let&#8217;s create a factory function for that vs. class constructors and imperative code property setting.</p>
<pre><code class="javascript">describe('getCannotReadEmailTemplateError when called', ()=&gt; {
    it('should give you an error message', ()=&gt; {
        expect(getCannotReadEmailTemplateError().message).to.equal('Cannot read email template')
    })
})
</code></pre>
<h1>Mutating Arrays &amp; Point Free</h1>
<p>The attachments code has a lot of mutation. It also makes the assumption at this point that the virus scan has already run and the files have a <code>scan</code> property. Mutation === bad. Assumption around order === imperative thinking === bad. Let&#8217;s fix both. You&#8217;re welcome to use <code>Array</code>&#8216;s native <code>map</code> and <code>filter</code> methods, I&#8217;m just using Lodash&#8217;s fp because they&#8217;re curried by default.</p>
<p>First, we need to filter only the files that have been scanned by the virus scanner. It&#8217;ll have a property on it called <code>scan</code>, and if the value does not equal lowercase &#8216;clean&#8217;, then we&#8217;ll assume it&#8217;s unsafe.</p>
<pre><code class="javascript">const filterCleanFiles = filter(
  file =&gt; get('scan', file) === 'clean'
)
</code></pre>
<p>You&#8217;ll notice we didn&#8217;t define a function here, we actually made one from calling <code>filter</code>. Lodash, Ramda, and other FP libraries are <a href="https://medium.com/javascript-scene/curry-or-partial-application-8150044c78b8">curried</a> by default. They put the most commonly known ahead of time parameters to the left, and the dynamic ones to the right. If you don&#8217;t provide all arguments, it&#8217;ll return a partial application (not to be confused with partial function which I do all the time). It&#8217;s also known as a &#8220;partially applied function&#8221;. The <code>filter</code> function takes 2 arguments, I&#8217;ve only applied 1, so it&#8217;ll return a function that has my arguments saved inside, and is simply waiting for the last parameter: the list to filter on.</p>
<p>You could write it as:</p>
<pre><code class="javascript">const filterCleanFiles = files =&gt; filter(
  file =&gt; get('scan', file) === 'clean',
  files
)
</code></pre>
<p>&#8230; but like <a href="https://www.youtube.com/watch?v=ynflf9W01vM">Jesse Warden&#8217;s mouth</a>, it&#8217;s too many, unneeded words. And to test:</p>
<pre><code class="javascript">describe('filterCleanFiles when called', ()=&gt; {
    it('should filter only clean files', ()=&gt; {
        const result = filterCleanFiles([
            {scan: 'clean'},
            {scan: 'unknown'},
            {scan: 'clean'}
        ])
        expect(result.length).to.equal(2)
    })
    it('should be empty if only whack files', () =&gt; {
        const result = filterCleanFiles([
            {},
            {},
            {}
        ])
        expect(result.length).to.equal(0)
    })
    it('should be empty no files', () =&gt; {
        const result = filterCleanFiles([])
        expect(result.length).to.equal(0)
    })
})
</code></pre>
<p>Note that the <a href="https://developer.mozilla.org/en-US/docs/Web/API/File">File object</a> is quite large in terms of number of properties. However, we&#8217;re just doing the bare minimum stubs to make the tests pass.</p>
<p>For <code>map</code>, however, we have a decision to make:</p>
<pre><code class="javascript">const mapFilesToAttachments = map(
  file =&gt; ({filename: get('originalname', file), path: get('path', file)})
)
</code></pre>
<p>If the files are either broken, or we misspelled something, we won&#8217;t really know. We&#8217;ll get <code>undefined</code>. Instead, we should provide some reasonable defaults to indicate what exactly failed. It isn&#8217;t perfect, but is throwing our future selves or fellow developers a bone to help clue them in on where to look. So, we&#8217;ll change to <code>getOr</code> instead of <code>get</code> to provide defaults:</p>
<pre><code class="javascript">const {
  get,
  getOr,
  filter,
  map
} = require('lodash/fp')
</code></pre>
<p>And the map:</p>
<pre><code class="javascript">const mapFilesToAttachments = map(
  file =&gt; ({
    filename: getOr('unknown originalname', 'originalname', file),
    path: get('unknown path', 'path', file)
  })
)
</code></pre>
<p>If point free functions (functions that don&#8217;t mention their arguments, also called &#8220;pointless&#8221; lol) aren&#8217;t comfortable for you, feel free to use instead:</p>
<pre><code class="javascript">const mapFilesToAttachments = files =&gt; map(
  file =&gt; ({
    filename: getOr('unknown originalname', 'originalname', file),
    path: get('unknown path', 'path', file)
  }),
    files
)
</code></pre>
<p>And the tests for both known, good values, and missing values:</p>
<pre><code class="javascript">describe('mapFilesToAttachments when called', ()=&gt; {
    it('should work with good stubs for filename', ()=&gt; {
        const result = mapFilesToAttachments([
            {originalname: 'cow'}
        ])
        expect(result[0].filename).to.equal('cow')
    })
    it('should work with good stubs for path', ()=&gt; {
        const result = mapFilesToAttachments([
            {path: 'of the righteous man'}
        ])
        expect(result[0].path).to.equal('of the righteous man')
    })
    it('should have reasonable default filename', ()=&gt; {
        const result = mapFilesToAttachments([{}])
        expect(result[0].filename).to.equal('unknown originalname')
    })
    it('should have reasonable default filename', ()=&gt; {
        const result = mapFilesToAttachments([{}])
        expect(result[0].path).to.equal('unknown path')
    })
})
</code></pre>
<p>We&#8217;re on a roll.</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-11.36.25-AM-259x300.png" alt="" width="259" height="300" class="alignleft size-medium wp-image-5511" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-11.36.25-AM-259x300.png 259w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-11.36.25-AM-768x890.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-10-at-11.36.25-AM.png 830w" sizes="auto, (max-width: 259px) 100vw, 259px" /></p>
<h1>Functional Code Calling Non-Functional Code</h1>
<p>As soon as you bring something impure into pure code, it&#8217;s impure. Nowhere is that more common than in JavaScript where most of our code calls 3rd party libraries we install via <a href="https://www.npmjs.com/">npm</a>, the package manager for JavaScript. JavaScript is not a functional language, and although a lot is written in FP style, most is not. Trust no one&#8230; including yourself.</p>
<p>Our email rendering uses an extremely popular templating engine called <a href="http://mustache.github.io/">Mustache</a>. You markup HTML with <code>{{yourVariableGoesHere}}</code>, and then call a function with the HTML template string, and your Object that has your variables, and poof, HTML with your data injected pops out. This was the basis for <a href="http://backbonejs.org/">Backbone</a>, and is similar to how <a href="https://angular.io/">Angular</a> and <a href="https://reactjs.org/">React</a> work.</p>
<p>However, it can throw. This can negatively affect the rest of our functions, even if sequester it in a Promise chain to contain the blast radius. Or maybe it doesn&#8217;t, it doesn&#8217;t really matter. If you don&#8217;t know the code, or you open up the source code in node_modules and do not see good error handling practices, just wrap with a try/catch, or Promise, and call it a day. We&#8217;ll take more about Promises built in error handling below in &#8220;Extra Credit&#8221;.</p>
<p>So, good ole&#8217; try/catch to the rescue.</p>
<pre><code class="javascript">const render = curry((renderFunction, template, value) =&gt; {
  try {
    const result = renderFunction(template, value)
    return Promise.resolve(result)
  } catch(error) {
    return Promise.reject(error)
  }
})
</code></pre>
<h2>Clearly Defining Your Dependencies &amp; Higher Order Functions</h2>
<p>A few things going on here, so let&#8217;s discuss each. Notice to make the function pure, we have to say where the <code>render</code> function is coming from. You can&#8217;t just import Mustache up top and use it; that&#8217;s a side effect or &#8220;outside thing that could effect&#8221; the function. Since JavaScript supports higher order functions (functions can be values, storied in variables, passed as function parameters, and returned from functions), we declare that first. Since everyone and their mom reading this code base knows at runtime in production code, that will be <code>Mustache.render</code>. For creating curried functions, you put the &#8220;most known/early thing first, dynamic/unknown things to the right&#8221;.</p>
<p>For unit tests, though, we&#8217;ll simply provide a stub, a function that just returns a string. We&#8217;re not in the business of testing 3rd party libraries, and we don&#8217;t want to have to mock it using <a href="http://sinonjs.org/">Sinon</a> which requires mutating 3rd party code before and after the tests, of which we didn&#8217;t want to test anyway.</p>
<h2>Creating Curried Functions</h2>
<p>Note it&#8217;s curried using the Lodash <code>curry</code> function. This means I can pass in <code>Mustache.render</code> as the first parameter, call it with the second parameter once the <code>fs</code> reads the email template string, and finally the 3rd parameter once we know the user&#8217;s information to email from the async <code>getUserEmail</code> call. For unit tests, we supply stubs for all 3 without any requirement for 3rd party libraries/dependencies. It&#8217;s implied you have to &#8220;figure out how they work&#8221; so you can properly stub them. This is where the lack of types forces you to go on the hunt into the source code.</p>
<h2>Error Handling</h2>
<p>Note the error handling via try catch and Promises. if we get a result, we can return it, else we return the Error. We&#8217;re using a Promise to clearly indicate there are only 2 ways this function can go: it worked and here&#8217;s your email template, or it didn&#8217;t and here&#8217;s why. Since it&#8217;s a Promise, it has the side benefit of being easy to chain with other Promises. This ensures no matter what happens in the render function, whether our fault or it, the function will remain pure from 3rd party libraries causing explosions.</p>
<p><strong>Note</strong>: This is not foolproof. Nor is using <a href="https://nodejs.org/api/process.html#process_event_uncaughtexception">uncaughtException</a> for global synchronous error handling, nor using <a href="https://nodejs.org/api/process.html#process_event_unhandledrejection">unhandledrejection</a> for global asynchronous error handling. Various stream API&#8217;s and others in Node can cause runtime exceptions that are uncaught and can exit the Node process. Just try your best.</p>
<h2>Extra Credit</h2>
<p>You could also utilize the built-in exception handling that promises (both native and most libraries like <a href="http://bluebirdjs.com/docs/getting-started.html">Bluebird</a>) have:</p>
<pre><code class="javascript">const render = curry((renderFunction, template, value) =&gt;
  new Promise( success =&gt; success(renderFunction(template, value))))
</code></pre>
<p>But the intent isn&#8217;t very clear form an imperative perspective. Meaning, &#8220;if it explodes in the middle of calling success, it&#8217;ll call failure&#8221;. So you could rewrite:</p>
<pre><code class="javascript">const render = curry((renderFunction, template, value) =&gt;
  new Promise( success =&gt; {
    const result = renderFunction(template, value)
    success(result)
  })
)
</code></pre>
<p>:: frownie face :: &#8220;Your call, rookie.&#8221;</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Dredd_012-287x300.jpg" alt="" width="287" height="300" class="alignleft size-medium wp-image-5513" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Dredd_012-287x300.jpg 287w, https://jessewarden.com/wp-content/uploads/2018/06/Dredd_012.jpg 618w" sizes="auto, (max-width: 287px) 100vw, 287px" /></p>
<h2>has and get vs. get or boom</h2>
<p>The <a href="https://github.com/lorenwest/node-config">config</a> module in Node is an special case. If the <code>config.get</code> method fails to find the key in the various places it could be (config.json, environment variables, etc), then it&#8217;ll throw. They recommend you use <code>config.has</code> first. Instead of using 2 functions, in a specific order, to compensate for 1 potentially failing, let&#8217;s just instead return a <code>Maybe</code> because maybe our configs will be there, or they won&#8217;t, and if they aren&#8217;t, we&#8217;ll just use default values.</p>
<pre><code class="javascript">const getEmailService = config =&gt;
  config.has('emailService')
  ? Just(config.get('emailService'))
  : Nothing()
</code></pre>
<p>And the tests:</p>
<pre><code class="javascript">describe('getEmailService when called', ()=&gt; {
    const configStub = { has: stubTrue, get: () =&gt; 'yup' }
    const configStubBad = { has: stubFalse }
    it('should work if config has defined value found', ()=&gt; {
        expect(getEmailService(configStub).getOrElse('nope')).to.equal('yup')
    })
    it('should work if config has defined value found', ()=&gt; {
        expect(getEmailService(configStubBad).getOrElse('nope')).to.equal('nope')
    })
})
</code></pre>
<p>Note that for our <code>has</code> stubs, we use <code>stubTrue</code> and <code>stubFalse</code>. Instead of writing <code>() =&gt; true</code>, you write <code>stubTrue</code>. Instead of writing <code>() =&gt; false</code>, you write <code>stubFalse</code>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
