<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>discuss &amp;mdash; Simple Engineering</title>
    <link>https://getsimple.works/tag:discuss</link>
    <description></description>
    <pubDate>Thu, 16 Apr 2026 22:51:28 +0000</pubDate>
    <item>
      <title>How to modularize socket.io/expressjs application </title>
      <link>https://getsimple.works/how-to-modularize-socket-io-expressjs-application?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[WebSocket protocol is an extension to the HTTP protocol that makes near real-time communication magic a reality. Adding this capability to an already complex application does not make large-scale applications any easier to work with. Using modularization techniques to decoupling the real-time portion of the application makes maintenance a little easier. The question is How do we get there?. This article applies modularization techniques to achieve that. &#xA;&#xA;  There is a wide variety of choice to choose from when it comes to WebSocket implementation in nodejs ecosystem. For simplicity, this blog post will provide examples using socket.io, but ideas expressed in this blog are applicable to any other nodejs WebSocket implementation.&#xA;&#xA;In this article we will talk about: &#xA;&#xA;How to modularize WebSocket for reusability &#xA;How to modularize WebSocket for testability &#xA;How to modularize WebSocket for composability &#xA;The need for a store manager in a nodejs WebSocket application  &#xA;How to integrate redis in a nodejs WebSocket application&#xA;How to modularize redis in  a nodejs WebSocket application&#xA;How to share session between an HTTP server and WebSocket server &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;//in server.js &#xA;var express = require(&#39;express&#39;); &#xA;var app = express();&#xA;...&#xA;app.get(&#39;/users/:id&#39;, function(req, res, next){&#xA;  User.findById(req.params.id, function(error, user){&#xA;    if(error) return next(error);&#xA;    return res.status(200).json(user);&#xA;  });&#xA;});&#xA;...&#xA;var server = require(&#39;http&#39;).createServer(app);&#xA;server.listen(app.get(&#39;port&#39;), () =  console.log(Listening on ${ process.env.PORT || 8080 }));&#xA;var wss = require(&#39;socket.io&#39;)(server);&#xA;//Handling realtime data&#xA;wss.on(&#39;connection|connect&#39;, (socket, event) =  {&#xA;    socket.on(&#39;error&#39;, () =  {});&#xA;    socket.on(&#39;pong&#39;, () =  {this.isAlive = true;});&#xA;    socket.on(&#39;disconnect&#39;, () =  {});&#xA;    socket.on(&#39;message&#39;, () =  {});&#xA;});&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;The following points may be a challenge when modularizing  WebSocket nodejs applications:&#xA;&#xA;WebSocket handlers are tightly coupled to the rest of the application. The challenge is how to reverse that.&#xA;How to modularize for optimal code reuse and easy testability &#xA;&#xA;The following sections will explore more on making points stated above work. &#xA;&#xA;How to modularize WebSocket for reusability &#xA;&#xA;When looking at the WebSocket handlers, there is something that strikes our eyes. Every handler has a signature that looks like any event handler common in the JavaScript ecosystem. We also realize that handlers are tightly coupled to the WebSocket object. To break the coupling, we can apply one technique: eject handlers from WebSocket, inject WebSocket and Socket objects whenever possible(composition).    &#xA;&#xA;How to modularize WebSocket for testability&#xA;&#xA;As noted earlier, the WebSocket event handlers are tightly coupled to the WebSocket object. Mocking the WebSocket object comes with a hefty price: to lose implementation of the handlers. To avoid that, we can tap into two techniques: eject handlers, and loading the WebSocket via a utility library.  &#xA;&#xA;How to modularize WebSocket for composability&#xA;&#xA;It is possible to shift the perspective on the way the application is adding WebSocket support. The question we can also ask is: Is it possible to restructure our code, in such a way that it requires only one line of code to wipe out the WebSocket support?. An alternative question would be: Is it possible to add WebSocket support to the base application, only using one line of code?. To answer these two questions, we will tap into a technique similar to the one we used to mount app instance to a set of routers(API for example)    &#xA;&#xA;The need of a store manager in a nodejs WebSocket application&#xA;&#xA;JavaScript, for that matter nodejs, is a single-threaded programming language. &#xA;&#xA;However, that does not mean that parallel computing is not feasible. The threading model can be replaced with a process-based model when it comes to parallel computing. This enhancement comes with an additional challenge: How to make it possible for processes to communicate or share data, especially when processes are running on two separate CPUs. &#xA;&#xA;The answer is using a third-party process/es that handles inter-process communications. Key stores are good examples that make the magic possible.   &#xA;&#xA;How to integrate redis in a nodejs WebSocket application&#xA;&#xA;redis comes with an expressive API that makes it easy to integrate with an existing nodejs application. &#xA;&#xA;It makes sense to question the approach used while adding this capability to the application. In the following example, any message received on the wire will be logged into the shared redis key store. &#xA;&#xA;All subscribed message listeners will then be notified about an incoming message. In the event there is a response to send back, the same approach will be followed, and the listener will be responsible to send the message again down the wire. This process may be repetitive, but it is one of the good ways to handle this kind of scenario. &#xA;&#xA;  There is an entire blog dedicated to modularizing redis clients here&#xA;&#xA;How to modularize redis in  a nodejs WebSocket application&#xA;&#xA;The example of integration with redis in nodejs application is tightly coupled to redis event handlers. Ejecting handlers can be a good starting point. Grouping ejected handlers in a module can follow suit. The next step in modularization can be composing(inject redis) on the resulting modules when needed.  &#xA;&#xA;How to share sessions between the HTTP server and WebSocket server. &#xA;&#xA;If we look closer, especially when dealing with namespaces, we find a similarity between HTTP requests(handled by express in our example) and WebSocket messages(handled by socket.io in our example). For applications that require authentication, or any other type of session on the server-side, it would be not necessary to have one authentication per protocol. To solve this problem, we will rely on a middleware that passes session data between two protocols.  &#xA;&#xA;Modularization reduces the complexity associated with large scale node js applications in general. We assume that socket.io/expressjs` applications won&#39;t be an exception in the current context. In a real-time context, we focus on making most parts accessible to be used by other components and tests. &#xA;&#xA;Express routes use socket.io instance to deliver some messages&#xA;Structure of a socket/socket.io enabled application looks like following: &#xA;&#xA;//module/socket.js&#xA;//server or express app instance &#xA;module.exports = function(server){&#xA;  var io = socket();&#xA;  io = io.listen(server);&#xA;  io.on(&#39;connect&#39;, fn); &#xA;  io.on(&#39;disconnect&#39;,fn);&#xA;};&#xA;    &#xA;//in server.js &#xA;var express = require(&#39;express&#39;); &#xA;var app = express();&#xA;var server = require(&#39;http&#39;).createServer(&#39;app&#39;);&#xA;&#xA;//Application app.js|server.js initialization, etc. &#xA;require(&#39;module/socket.js&#39;)(server);       &#xA;        &#xA;&#xA;For socket.io app to use same Express server instance or sharing route instance with socket.io server&#xA;&#xA;//routes.js - has all routes initializations&#xA;var route = require(&#39;express&#39;).Router();&#xA;module.exports = function(){&#xA;    route.all(&#39;&#39;,function(req, res, next){ &#xA;    &#x9;res.send(); &#xA;    &#x9;next();&#xA; });&#xA;};&#xA;&#xA;//socket.js - has socket communication code&#xA;var io = require(&#39;socket.io&#39;);&#xA;module.exports = function(server){&#xA;  //server will be provided by the calling application&#xA;  //server = require(&#39;http&#39;).createServer(app);&#xA;  io = io.listen(server);&#xA;  return io;&#xA;};&#xA;&#xA;Socket Session sharing &#xA;&#xA;Sharing session between socket.io and Express application&#xA;&#xA;//@link http://stackoverflow.com/a/25618636/132610&#xA;//Sharing session data between socket.io and Express &#xA;sio.use(function(socket, next) {&#xA;    sessionMiddleware(socket.request, socket.request.res, next);&#xA;});&#xA;&#xA;Conclusion&#xA;&#xA;Modularization is a key strategy in crafting re-usable composable software. Modularization brings not only elegance but makes copy/paste detectors happy, and at the same time improves both performance and testability. &#xA;&#xA;In this article, we revisited how to aggregate WebSocket code into composable and testable modules. The need to group related tasks into modules involves the ability to add support of Pub/Sub on demand and using various solutions as project requirements evolve. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book.  &#xA;&#xA;References + Reading List&#xA;&#xA;Testing nodejs Applications book&#xA;redis pubsub library ~ A Github cloned library&#xA;Building a Chat Server with node and redis - tests ~ Matthew Daly Blog&#xA;High Volume, low latency difficulties nodejs/pubsub/redis ~ StackOverflow Question&#xA;examples using redis-store with socket.io ~ StackOverflow Question&#xA;Using redis as PubSub over socket.io ~ StackOverflow Question&#xA;socket.io-redis ~ Github Library&#xA;socket.io within concurrent processes ~ Tolle Iv Blog&#xA;nodejs, expressjs and socket.io application ~ DeveloperIQ Blog&#xA;Modularize Your Chat App(or How to Write a nodejs Express App in More Than One File) ~ Philosophy is Thinking Medium&#xA;bacon.js + nodejs + mongodb: Functional Reactive Programming on the Server ~ Carbon Five Blog&#xA;Modularizing socket.io with expressjs@4 ~ StackOverflow Answer&#xA;&#xA;tags: #snippets #code #annotations #question #discuss&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>WebSocket protocol is an extension to the HTTP protocol that makes near real-time communication magic a reality. Adding this capability to an already complex application does not make large-scale applications any easier to work with. Using modularization techniques to decoupling the real-time portion of the application makes maintenance a little easier. The question is <em>How do we get there?</em>. This article applies modularization techniques to achieve that.</p>

<blockquote><p>There is a wide variety of choice to choose from when it comes to WebSocket implementation in <code>nodejs</code> ecosystem. For simplicity, this blog post will provide examples using <code>socket.io</code>, but ideas expressed in this blog are applicable to any other <code>nodejs</code> WebSocket implementation.</p></blockquote>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>How to modularize WebSocket for reusability</li>
<li>How to modularize WebSocket for testability</li>
<li>How to modularize WebSocket for composability</li>
<li>The need for a store manager in a <code>nodejs</code> WebSocket application<br/></li>
<li>How to integrate <code>redis</code> in a <code>nodejs</code> WebSocket application</li>
<li>How to modularize <code>redis</code> in  a <code>nodejs</code> WebSocket application</li>
<li>How to share session between an HTTP server and WebSocket server</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<pre><code class="language-JavaScript">//in server.js 
var express = require(&#39;express&#39;); 
var app = express();
...
app.get(&#39;/users/:id&#39;, function(req, res, next){
  User.findById(req.params.id, function(error, user){
    if(error) return next(error);
    return res.status(200).json(user);
  });
});
...
var server = require(&#39;http&#39;).createServer(app);
server.listen(app.get(&#39;port&#39;), () =&gt; console.log(`Listening on ${ process.env.PORT || 8080 }`));
var wss = require(&#39;socket.io&#39;)(server);
//Handling realtime data
wss.on(&#39;connection|connect&#39;, (socket, event) =&gt; {
    socket.on(&#39;error&#39;, () =&gt; {});
    socket.on(&#39;pong&#39;, () =&gt; {this.isAlive = true;});
    socket.on(&#39;disconnect&#39;, () =&gt; {});
    socket.on(&#39;message&#39;, () =&gt; {});
});
</code></pre>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>

<p>The following points may be a challenge when modularizing  WebSocket <code>nodejs</code> applications:</p>
<ul><li>WebSocket handlers are tightly coupled to the rest of the application. The challenge is <strong><em>how to reverse that</em></strong>.</li>
<li>How to modularize for optimal code reuse and easy testability</li></ul>

<p>The following sections will explore more on making points stated above work.</p>

<h2 id="how-to-modularize-websocket-for-reusability" id="how-to-modularize-websocket-for-reusability">How to modularize WebSocket for reusability</h2>

<p>When looking at the WebSocket handlers, there is something that strikes our eyes. Every handler has a signature that looks like any event handler common in the JavaScript ecosystem. We also realize that handlers are tightly coupled to the WebSocket object. To break the coupling, we can apply one technique: eject handlers from WebSocket, inject WebSocket and Socket objects whenever possible(composition).</p>

<h2 id="how-to-modularize-websocket-for-testability" id="how-to-modularize-websocket-for-testability">How to modularize WebSocket for testability</h2>

<p>As noted earlier, the WebSocket event handlers are tightly coupled to the WebSocket object. Mocking the WebSocket object comes with a hefty price: to lose implementation of the handlers. To avoid that, we can tap into two techniques: eject handlers, and loading the WebSocket via a utility library.</p>

<h2 id="how-to-modularize-websocket-for-composability" id="how-to-modularize-websocket-for-composability">How to modularize WebSocket for composability</h2>

<p>It is possible to shift the perspective on the way the application is adding WebSocket support. The question we can also ask is: <em>Is it possible to restructure our code, in such a way that it requires only one line of code to wipe out the WebSocket support?</em>. An alternative question would be: <em>Is it possible to add WebSocket support to the base application, only using one line of code?</em>. To answer these two questions, we will tap into a technique similar to the one we used to mount <code>app</code> instance to a set of routers(API for example)</p>

<h2 id="the-need-of-a-store-manager-in-a-nodejs-websocket-application" id="the-need-of-a-store-manager-in-a-nodejs-websocket-application">The need of a store manager in a <code>nodejs</code> WebSocket application</h2>

<p>JavaScript, for that matter <code>nodejs</code>, is a single-threaded programming language.</p>

<p>However, that does not mean that parallel computing is not feasible. The threading model can be replaced with a process-based model when it comes to parallel computing. This enhancement comes with an additional challenge: How to make it possible for processes to communicate or share data, especially when processes are running on two separate CPUs.</p>

<p>The answer is using a third-party process/es that handles inter-process communications. Key stores are good examples that make the magic possible.</p>

<h2 id="how-to-integrate-redis-in-a-nodejs-websocket-application" id="how-to-integrate-redis-in-a-nodejs-websocket-application">How to integrate <code>redis</code> in a <code>nodejs</code> WebSocket application</h2>

<p><code>redis</code> comes with an expressive API that makes it easy to integrate with an existing <code>nodejs</code> application.</p>

<p>It makes sense to question the approach used while adding this capability to the application. In the following example, any message received on the wire will be logged into the shared <code>redis</code> key store.</p>

<p>All subscribed message listeners will then be notified about an incoming message. In the event there is a response to send back, the same approach will be followed, and the listener will be responsible to send the message again down the wire. This process may be repetitive, but it is one of the good ways to handle this kind of scenario.</p>

<blockquote><p>There is an entire blog dedicated to <a href="./how-to-modularize-redis-clients">modularizing <code>redis</code> clients here</a></p></blockquote>

<h2 id="how-to-modularize-redis-in-a-nodejs-websocket-application" id="how-to-modularize-redis-in-a-nodejs-websocket-application">How to modularize <code>redis</code> in  a <code>nodejs</code> WebSocket application</h2>

<p>The example of integration with <code>redis</code> in <code>nodejs</code> application is tightly coupled to <code>redis</code> event handlers. Ejecting handlers can be a good starting point. Grouping ejected handlers in a module can follow suit. The next step in modularization can be composing(inject <code>redis</code>) on the resulting modules when needed.</p>

<h2 id="how-to-share-sessions-between-the-http-server-and-websocket-server" id="how-to-share-sessions-between-the-http-server-and-websocket-server">How to share sessions between the HTTP server and WebSocket server.</h2>

<p>If we look closer, especially when dealing with namespaces, we find a similarity between HTTP requests(handled by express in our example) and WebSocket messages(handled by <code>socket.io</code> in our example). For applications that require authentication, or any other type of session on the server-side, it would be not necessary to have one authentication per protocol. To solve this problem, we will rely on a middleware that passes session data between two protocols.</p>

<p>Modularization reduces the complexity associated with large scale <code>node js applications in general. We assume that</code>socket.io<code>/</code>expressjs` applications won&#39;t be an exception in the current context. In a real-time context, we focus on making most parts accessible to be used by other components and tests.</p>

<p>Express routes use <code>socket.io</code> instance to deliver some messages
Structure of a <code>socket/socket.io</code> enabled application looks like following:</p>

<pre><code class="language-JavaScript">//module/socket.js
//server or express app instance 
module.exports = function(server){
  var io = socket();
  io = io.listen(server);
  io.on(&#39;connect&#39;, fn); 
  io.on(&#39;disconnect&#39;,fn);
};
    
//in server.js 
var express = require(&#39;express&#39;); 
var app = express();
var server = require(&#39;http&#39;).createServer(&#39;app&#39;);

//Application app.js|server.js initialization, etc. 
require(&#39;module/socket.js&#39;)(server);       
        
</code></pre>

<p>For <code>socket.io</code> app to use same Express server instance or sharing route instance with <code>socket.io</code> server</p>

<pre><code class="language-JavaScript">//routes.js - has all routes initializations
var route = require(&#39;express&#39;).Router();
module.exports = function(){
    route.all(&#39;&#39;,function(req, res, next){ 
    	res.send(); 
    	next();
 });
};

//socket.js - has socket communication code
var io = require(&#39;socket.io&#39;);
module.exports = function(server){
  //server will be provided by the calling application
  //server = require(&#39;http&#39;).createServer(app);
  io = io.listen(server);
  return io;
};
</code></pre>

<h2 id="socket-session-sharing" id="socket-session-sharing">Socket Session sharing</h2>

<p>Sharing session between <code>socket.io</code> and Express application</p>

<pre><code class="language-JavaScript">//@link http://stackoverflow.com/a/25618636/132610
//Sharing session data between `socket.io` and Express 
sio.use(function(socket, next) {
    sessionMiddleware(socket.request, socket.request.res, next);
});
</code></pre>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Modularization is a key strategy in crafting re-usable composable software. Modularization brings not only elegance but makes copy/paste detectors happy, and at the same time improves both performance and testability.</p>

<p>In this article, we revisited how to aggregate WebSocket code into composable and testable modules. The need to group related tasks into modules involves the ability to add support of Pub/Sub on demand and using various solutions as project requirements evolve. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references-reading-list" id="references-reading-list">References + Reading List</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li><code>redis</code> <code>pubsub</code> library ~ <a href="https://github.com/murindwaz/redispubsub">A Github cloned library</a></li>
<li>Building a Chat Server with node and <code>redis</code> – tests ~ <a href="https://matthewdaly.co.uk/blog/2014/12/31/building-a-chat-server-with-node-dot-js-and-redis/">Matthew Daly Blog</a></li>
<li>High Volume, low latency difficulties <code>nodejs</code>/<code>pubsub</code>/<code>redis</code> ~ <a href="https://stackoverflow.com/questions/10557826/node-js-socket-io-redis-pub-sub-high-volume-low-latency-difficulties">StackOverflow Question</a></li>
<li>examples using <code>redis-store</code> with <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/9267292/examples-in-using-redisstore-in-socket-io">StackOverflow Question</a></li>
<li>Using <code>redis</code> as PubSub over <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/32743754/using-redis-as-pubsub-over-socket-io">StackOverflow Question</a></li>
<li><code>socket.io-redis</code> ~ <a href="https://github.com/socketio/socket.io-redis">Github Library</a></li>
<li><code>socket.io</code> within concurrent processes ~ <a href="https://blog.tolleiv.de/2014/05/socket-dot-io-within-concurrent-processes/">Tolle Iv Blog</a></li>
<li><code>nodejs</code>,<code>expressjs</code> and <code>socket.io</code> application ~ <a href="https://developeriq.in/articles/2015/feb/03/nodeexpressjs-and-socketio-application/">DeveloperIQ Blog</a></li>
<li>Modularize Your Chat App(or How to Write a nodejs Express App in More Than One File) ~ <a href="https://medium.com/philosophie-is-thinking/modularize-your-chat-app-or-how-to-write-a-node-js-express-app-in-more-than-one-file-bfae2d6b69df#.hfb4r6z3i">Philosophy is Thinking Medium</a></li>
<li><code>bacon.js</code> + <code>nodejs</code> + <code>mongodb</code>: Functional Reactive Programming on the Server ~ <a href="https://blog.carbonfive.com/2014/09/23/bacon-js-node-js-mongodb-functional-reactive-programming-on-the-server/">Carbon Five Blog</a></li>
<li>Modularizing <code>socket.io</code> with <code>expressjs@4</code> ~ <a href="https://stackoverflow.com/a/29697470/132610">StackOverflow Answer</a></li></ul>

<p>tags: <a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-to-modularize-socket-io-expressjs-application</guid>
      <pubDate>Thu, 17 Jun 2021 06:17:51 +0000</pubDate>
    </item>
    <item>
      <title>How to modularize test doubles</title>
      <link>https://getsimple.works/how-to-modularize-test-doubles?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[The ever-growing number of files does not spare test files. The number of similar test double files can be used as an indication of a need to refactor or modularize, test doubles. This blog applies the same techniques we used to modularize other layers of a nodejs application, but in an automated testing context. &#xA;&#xA;In this article we will talk about: &#xA;&#xA;The need to have test doubles&#xA;How utilities library relates to fixtures library &#xA;Reducing repetitive imports via a unified export library &#xA;How to modularize fixtures of spies &#xA;How to modularize fixtures of mock data &#xA;How to modularize fixtures of fakes &#xA;How to modularize fixtures of stubs &#xA;How to modularize test doubles for reusability &#xA;How to modularize test doubles for composability &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;var should = require(&#39;should&#39;);&#xA;var expect = require(&#39;expect&#39;);&#xA;var chai = require(&#39;chai&#39;);&#xA;Example:&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;The following points may be a challenge when modularizing test doubles:&#xA;&#xA;Some testing libraries share dependencies with the project they are supposed to tests &#xA;Individual test doubles can be replicated in multiple places &#xA;With this knowledge, How can we reduce the waste and reuse most of the dependencies?&#xA;&#xA;In the next sections, we make a case on modularization for reusability as a solution to reduce code duplication. &#xA;&#xA;The Status Quo&#xA;&#xA;Every test double library is in fact an independent library. That remains true even when some libraries are bundled and shipped together, as is the case for chai(ships with should and expect). Every mock, every spy, and every stub we make in one place can potentially be replicated to multiple other places that test similar code-blocks, or code-blocks that share dependencies. &#xA;&#xA;One of the solutions to share common test double configurations across multiple test cases is to organize test doubles in modules. &#xA;&#xA;The need to have test doubles in tests. &#xA;&#xA;In these series, there is one blog  that discusses the difference between various test doubles: spy/mock/stubs/fake and fixtures. For the sake of brevity, that will not be our concern for the moment. Our concern is to reflect on the why we should have test doubles in the first place. &#xA;&#xA;From the time and cost perspective, It takes longer to load one single file. It would take even longer to load multiple files, be in parallel or sequentially. The higher the number of test cases spanning multiple files, the slower the test runner process will take to complete execution. This adds more execution time, to an already slow process. &#xA;&#xA;If there is one of amongst other improvements that would save us time, reusing the same library quite often while mimicking implementation of other things we don&#39;t really need to load(mocking/etc.), would be one of them. &#xA;&#xA;Testing code acts as a state machine, or pure functions, every input results in the same output. Test doubles are essentially tools that can help us save time and cost as a drop-in replacement of expected behaviors. &#xA;&#xA;How utilities relate to fixtures &#xA;&#xA;In this section, we pause a little bit to answer the question: &#34;How utilities library relates to fixtures library&#34;. &#xA;&#xA;Utility libraries(utilities) provide some tools that are not necessarily related to the core business of the program, but necessary to complete a set of tasks. The need to have utilities is not limited to business logic only, but also to testing code. In the context of tests, the utilities are going to be referred to as fixtures. Fixtures can have computations or data that emulates a state under which the program has to be tested.    &#xA;&#xA;Grouping imports with unified export library&#xA;&#xA;The module system provided by the nodejs is a double-edged sword. It presents opportunities to create granular systems, but repetitive imports weakness the performance of the application. &#xA;&#xA;To reduce repetitive imports, we make good use of the index. This compensates for our rejection to attach modules to the global object. It also makes it possible to abstract away the file structure: one doesn&#39;t have to know the whole project&#39;s structure to import just one single function.  &#xA;&#xA;How to modularize fixtures of spies&#xA;&#xA;The modularization of spies takes one step in general. Since the spies already have a name, It makes sense to group them under the fixture library, by category or feature, and export the resulting module. The use of the index file makes it possible to export complex file systems via one single import(or export depending on perspective).  &#xA;&#xA;How to modularize fixtures of mock data&#xA;&#xA;Mock data is the cornerstone to simulate desired test state when one kind of data is injected into a function/system. Grouping related data under the same umbrella makes sense in most cases. After the fact, it makes sense to manifest data via export constructs.   &#xA;&#xA;How to modularize fixtures of fakes&#xA;&#xA;Fakes are functions similar to implementation they are designed to replace, most of the time third-party functionality, that can be used to simulate original behavior. When two or more fakes share striking similarities, they become good candidates for mergers, refactoring, and modularization.    &#xA;&#xA;How to modularize fixtures of stubs&#xA;&#xA;Stubs are most of the time taken as mocks. That is because they tend to operate in similar use cases. A stub is a fake that replaces real implementations, and capable of receiving and producing a pre-determined outcome using mock data. The modularization will take a single step, in case the stub is already named. The last step is to actually export and reveal/expose the function as an independent/exportable function.  &#xA;&#xA;How to modularize test doubles for reusability&#xA;&#xA;Test doubles are reusable in nature. There is no difference between designing functions/classes and test doubles for reusability per se. To be able to reuse a class/function, that function has to be exposed to the external world. That is where export construct comes into the picture.   &#xA;&#xA;How to modularize test doubles for composability&#xA;&#xA;The composability on the other side is the ability for one module to be reusable. For that to happen, the main client that is going to be using the library has to be injected into the library, either via a thunk or similar strategy. The following example shows how two or more test doubles can be modularized for composability.  &#xA;&#xA;  Some Stubbing questions we have to keep in mind &#xA;  - How do Stubbing differ from Mocking &#xA;  - How to Stubbing differs from Spying: Spies/Stubs functions with pre-programmed behavior &#xA;  - How to know if a function has been called with a specific argument?: For example: I want to know the res.status(401).send() -- more has been discussed in this blog as well: spy/mock/stubs/fake and fixtures&#xA;&#xA;Making chai, should and expect accessible &#xA;&#xA;The approach explained below makes it possible to make pre-configured chai available in a global context, without attaching chai explicitly to the global Object. &#xA;&#xA;There are multiple ways to go with modularization, but the most basic is using exports. &#xA;This technique will not make any library default but is designed to reduce the boilerplate when testing. &#xA;&#xA;var chai = require(&#39;chai&#39;);&#xA;module.exports.chai = chai; &#xA;module.exports.should = chai.should; &#xA;module.exports.expect = chai.expect; &#xA;Example:&#xA;&#xA;Conclusion&#xA;&#xA;Modularization is a key strategy in crafting re-usable composable software. Modularization brings elegance, improves performance, and in this case, re-usability of test doubles across the board. &#xA;&#xA;In this article, we revisited how to test double modularization can be achieved by leveraging the power of module.exports( or export in ES7+). The ever-increasing number of similar test double instances make them good candidates to modularize, at the same time makes it is imperative that the modularization has to be minimalistic. That is the reason why we leveraged the index file to make sure we do not overload already complex architectures. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book, on this very same subject.&#xA;&#xA;References &#xA;&#xA;Testing nodejs Applications book&#xA;How to add global variables used by all tests in Javascript? StackOverflow Question &#xA;Problem resetting global object. Bug#1 about adding should on global object&#xA;Problem resetting global object. Bug#2 How to make expect/should/assert be global in test files and be able to pass eslint&#xA;Test doubles ~ Martin Fowler Blog&#xA;Jasmine vs. Mocha, Chai, and Sinon&#xA;Mocking Model Level&#xA;&#xA;tags: #snippets #nodejs #spy #fake #mock #stub #test-doubles #question #discuss&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>The ever-growing number of files does not spare test files. The number of similar <em>test double</em> files can be used as an indication of a need to refactor or modularize, <em>test doubles</em>. This blog applies the same techniques we used to modularize other layers of a <code>nodejs</code> application, but in an automated testing context.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>The need to have test doubles</li>
<li>How <strong>utilities</strong> library relates to <strong>fixtures</strong> library</li>
<li>Reducing repetitive imports via a unified export library</li>
<li>How to modularize fixtures of <strong>spies</strong></li>
<li>How to modularize fixtures of <strong>mock</strong> data</li>
<li>How to modularize fixtures of <strong>fakes</strong></li>
<li>How to modularize fixtures of <strong>stubs</strong></li>
<li>How to modularize test doubles for reusability</li>
<li>How to modularize test doubles for composability</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<pre><code class="language-JavaScript">var should = require(&#39;should&#39;);
var expect = require(&#39;expect&#39;);
var chai = require(&#39;chai&#39;);
</code></pre>

<p><em><em>Example</em>:</em></p>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>

<p>The following points may be a challenge when modularizing test doubles:</p>
<ul><li>Some testing libraries share dependencies with the project they are supposed to tests</li>
<li>Individual test doubles can be replicated in multiple places</li>
<li>With this knowledge, How can we reduce the waste and reuse most of the dependencies?</li></ul>

<p>In the next sections, we make a case on modularization for reusability as a solution to reduce code duplication.</p>

<h2 id="the-status-quo" id="the-status-quo">The <em>Status Quo</em></h2>

<p>Every <em>test double</em> library is in fact an independent library. That remains true even when some libraries are bundled and shipped together, as is the case for <code>chai</code>(ships with <code>should</code> and <code>expect</code>). Every <code>mock</code>, every <code>spy</code>, and every <code>stub</code> we make in one place can potentially be replicated to multiple other places that test similar code-blocks, or code-blocks that share dependencies.</p>

<p>One of the solutions to share common test double configurations across multiple test cases is to organize test doubles in modules.</p>

<h2 id="the-need-to-have-test-doubles-in-tests" id="the-need-to-have-test-doubles-in-tests">The need to have test doubles in tests.</h2>

<p>In these series, there is one blog  that discusses the difference between various test doubles: <a href="./test-doubles-jasmine-jest-mocha-chai-sinon">spy/mock/stubs/fake and fixtures</a>. For the sake of brevity, that will not be our concern for the moment. Our concern is to reflect on the <em>why</em> we should have test doubles in the first place.</p>

<p>From the <em>time and cost</em> perspective, It takes longer to load one single file. It would take even longer to load multiple files, be in parallel or sequentially. The higher the number of test cases spanning multiple files, the slower the test runner process will take to complete execution. This adds more execution time, to an already slow process.</p>

<p>If there is one of amongst other improvements that would save us time, reusing the same library quite often while mimicking implementation of other things we don&#39;t really need to load(mocking/etc.), would be one of them.</p>

<p>Testing code acts as a state machine, or pure functions, every input results in the same output. <em>Test doubles</em> are essentially tools that can help us save <em>time and cost</em> as a drop-in replacement of expected behaviors.</p>

<h2 id="how-utilities-relate-to-fixtures" id="how-utilities-relate-to-fixtures">How utilities relate to fixtures</h2>

<p>In this section, we pause a little bit to answer the question: <em>“How <strong>utilities</strong> library relates to <strong>fixtures</strong> library”</em>.</p>

<p>Utility libraries(utilities) provide some tools that are not necessarily related to the core business of the program, but necessary to complete a set of tasks. The need to have utilities is not limited to business logic only, but also to testing code. In the context of tests, the utilities are going to be referred to as <em>fixtures</em>. Fixtures can have computations or data that emulates a state under which the program has to be tested.</p>

<h2 id="grouping-imports-with-unified-export-library" id="grouping-imports-with-unified-export-library">Grouping imports with unified export library</h2>

<p>The module system provided by the <code>nodejs</code> is a double-edged sword. It presents opportunities to create granular systems, but repetitive imports weakness the performance of the application.</p>

<p>To reduce repetitive imports, we make good use of the <code>index</code>. This compensates for our rejection to attach modules to the global object. It also makes it possible to abstract away the file structure: one doesn&#39;t have to know the whole project&#39;s structure to import just one single function.</p>

<h2 id="how-to-modularize-fixtures-of-spies" id="how-to-modularize-fixtures-of-spies">How to modularize fixtures of <strong>spies</strong></h2>

<p>The modularization of spies takes one step in general. Since the spies already have a name, It makes sense to group them under the fixture library, by category or feature, and export the resulting module. The use of the <code>index</code> file makes it possible to export complex file systems via one single import(or export depending on perspective).</p>

<h2 id="how-to-modularize-fixtures-of-mock-data" id="how-to-modularize-fixtures-of-mock-data">How to modularize fixtures of <strong>mock</strong> data</h2>

<p>Mock data is the cornerstone to simulate desired test state when one kind of data is injected into a function/system. Grouping related data under the same umbrella makes sense in most cases. After the fact, it makes sense to manifest data via <code>export</code> constructs.</p>

<h2 id="how-to-modularize-fixtures-of-fakes" id="how-to-modularize-fixtures-of-fakes">How to modularize fixtures of <strong>fakes</strong></h2>

<p>Fakes are functions similar to implementation they are designed to replace, most of the time third-party functionality, that can be used to simulate original behavior. When two or more fakes share striking similarities, they become good candidates for mergers, refactoring, and modularization.</p>

<h2 id="how-to-modularize-fixtures-of-stubs" id="how-to-modularize-fixtures-of-stubs">How to modularize fixtures of <strong>stubs</strong></h2>

<p>Stubs are most of the time taken as mocks. That is because they tend to operate in similar use cases. A stub is a fake that replaces real implementations, and capable of receiving and producing a pre-determined outcome using <em>mock data</em>. The modularization will take a single step, in case the stub is already named. The last step is to actually export and reveal/expose the function as an independent/exportable function.</p>

<h2 id="how-to-modularize-test-doubles-for-reusability" id="how-to-modularize-test-doubles-for-reusability">How to modularize test doubles for reusability</h2>

<p>Test doubles are reusable in nature. There is no difference between designing functions/classes and test doubles for reusability <em>per se</em>. To be able to reuse a class/function, that function has to be exposed to the external world. That is where <code>export</code> construct comes into the picture.</p>

<h2 id="how-to-modularize-test-doubles-for-composability" id="how-to-modularize-test-doubles-for-composability">How to modularize test doubles for composability</h2>

<p>The composability on the other side is the ability for one module to be reusable. For that to happen, the main client that is going to be using the library has to be injected into the library, either via a thunk or similar strategy. The following example shows how two or more test doubles can be modularized for composability.</p>

<blockquote><p>Some Stubbing questions we have to keep in mind
– How do Stubbing differ from Mocking
– How to Stubbing differs from Spying: Spies/Stubs functions with pre-programmed behavior
– How to know if a function has been called with a specific argument?: For example: I want to know the <code>res.status(401).send()</code> — more has been discussed in this blog as well: <a href="./test-doubles-jasmine-jest-mocha-chai-sinon">spy/mock/stubs/fake and fixtures</a></p></blockquote>

<h2 id="making-chai-should-and-expect-accessible" id="making-chai-should-and-expect-accessible">Making <code>chai</code>, <code>should</code> and <code>expect</code> accessible</h2>

<p>The approach explained below makes it possible to make pre-configured <code>chai</code> available in a global context, without attaching <code>chai</code> explicitly to the global Object.</p>
<ul><li>There are multiple ways to go with modularization, but the most basic is using exports.</li>
<li>This technique will not make any library default but is designed to reduce the boilerplate when testing.</li></ul>

<pre><code class="language-JavaScript">var chai = require(&#39;chai&#39;);
module.exports.chai = chai; 
module.exports.should = chai.should; 
module.exports.expect = chai.expect; 
</code></pre>

<p><em><em>Example</em>:</em></p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Modularization is a key strategy in crafting re-usable composable software. Modularization brings elegance, improves performance, and in this case, re-usability of test doubles across the board.</p>

<p>In this article, we revisited how to test double <strong>modularization</strong> can be achieved by leveraging the power of <code>module.exports</code>( or <code>export</code> in ES7+). The ever-increasing number of similar test double instances make them good candidates to modularize, at the same time makes it is imperative that the modularization has to be minimalistic. That is the reason why we leveraged the <code>index</code> file to make sure we do not overload already complex architectures. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book, on this very same subject.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>How to add global variables used by all tests in Javascript? <a href="https://stackoverflow.com/q/28449902/132610">StackOverflow Question</a></li>
<li>Problem resetting global object. <a href="https://github.com/chaijs/chai/issues/86">Bug#1 about adding should on global object</a></li>
<li>Problem resetting global object. <a href="https://github.com/chaijs/chai/issues/891">Bug#2 How to make expect/should/assert be global in test files and be able to pass <code>eslint</code></a></li>
<li>Test doubles ~ <a href="https://martinfowler.com/bliki/TestDouble.html">Martin Fowler Blog</a></li>
<li><a href="https://thejsguy.com/2015/01/12/jasmine-vs-mocha-chai-and-sinon.html">Jasmine vs. Mocha, Chai, and Sinon</a></li>
<li><a href="https://semaphoreci.com/community/tutorials/a-tdd-approach-to-building-a-todo-api-using-node-js-and-mongodb">Mocking Model Level</a></li></ul>

<p>tags: <a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:nodejs" class="hashtag"><span>#</span><span class="p-category">nodejs</span></a> <a href="https://getsimple.works/tag:spy" class="hashtag"><span>#</span><span class="p-category">spy</span></a> <a href="https://getsimple.works/tag:fake" class="hashtag"><span>#</span><span class="p-category">fake</span></a> <a href="https://getsimple.works/tag:mock" class="hashtag"><span>#</span><span class="p-category">mock</span></a> <a href="https://getsimple.works/tag:stub" class="hashtag"><span>#</span><span class="p-category">stub</span></a> <a href="https://getsimple.works/tag:test" class="hashtag"><span>#</span><span class="p-category">test</span></a>-doubles <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-to-modularize-test-doubles</guid>
      <pubDate>Thu, 17 Jun 2021 06:15:05 +0000</pubDate>
    </item>
    <item>
      <title>How Spy/Stub or fake a functions</title>
      <link>https://getsimple.works/how-spy-stub-or-fake-a-functions?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Testing functions attached to objects, other than a class instance, constitutes an intimidating edge case from first sight. Such objects range from object literals to modules. This blog explores some test doubles techniques to shine a light on such cases. &#xA;&#xA;  For context, the difference between a function and a method, is that a method is a function encapsulated into a class. &#xA;&#xA;In this article we will talk about: &#xA;&#xA;Key difference between a spy, stub, and a fake&#xA;When it makes sense a spy over a stub&#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;var fs = require(&#39;fs&#39;);&#xA;&#xA;module.exports.removeUserPhoto = function(req, res, next){&#xA;    let filepath = /path/to/photos/${req.params.photoId}.jpg;&#xA;    fs.unlink(filepath, (error) =  {&#xA;        if(error) return next(error);&#xA;        return res.status(200).json({&#xA;            message: Your photo is removed - Photo ID was ${req.params.photoId}&#xA;        });&#xA;    });    &#xA;}&#xA;Example: A simple controller that takes a PhotoID and deletes files associated to it&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;Some challenges when mocking chained functions:&#xA;&#xA;Stubbing a method, while keeping original callback behavior intact &#xA;&#xA;Show me the tests &#xA;&#xA;From the How to mock chained functions article, there are three relevant to the current context avenues we leverage for our mocking strategy.  &#xA;&#xA;let outputMock = { ... };&#xA;sinon.stub(obj, &#39;func&#39;).returns(outputMock);&#xA;sinon.stub(obj, &#39;func&#39;).callsFake(function fake(){ return outputMock; })&#xA;let func = sinon.spy(function fake(){ return outputMock; });&#xA;&#xA;We can put those approaches to test in the following test case &#xA;&#xA;var sinon = require(&#39;sinon&#39;);&#xA;var assert = require(&#39;chai&#39;).assert;&#xA;&#xA;// Somewhere in your code. &#xA;it(&#39;#fs:unlink removes a file&#39;, function () {&#xA;    this.fs = require(&#39;fs&#39;);&#xA;    var func = function(fn){ return fn.apply(this, arguments); };//mocked behaviour &#xA;    &#xA;    //Spy + Stubbing fs.unlink function, to avoid a real file removal&#xA;    var unlink = sinon.stub(this.fs, &#34;unlink&#34;, func);&#xA;    assert(this.fs.unlink.called, &#34;#unlink() has been called&#34;);&#xA;&#xA;    unlink.restore(); //restoring default function &#xA;});&#xA;&#xA;Conclusion&#xA;&#xA;In this article, we established the difference between stub/spy and fake concepts, how they work in concert to deliver effective test doubles, and how to leverage their drop-in-replacement capabilities when testing functions. &#xA;&#xA;Testing tends to be more of art, than a science, practice makes perfect. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References &#xA;&#xA;Testing nodejs Applications book&#xA;Evan Hahn in &#34;How do I Jasmine&#34; - has pretty good examples that leverages spies along the way. &#xA;&#xA;tags: #snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>Testing functions attached to objects, other than a class instance, constitutes an intimidating edge case from first sight. Such objects range from object literals to modules. This blog explores some test doubles techniques to shine a light on such cases.</p>

<blockquote><p>For context, the difference between a function and a method, is that a method is a function encapsulated into a class.</p></blockquote>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Key difference between a spy, stub, and a fake</li>
<li>When it makes sense a spy over a stub</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<pre><code class="language-JavaScript">var fs = require(&#39;fs&#39;);

module.exports.removeUserPhoto = function(req, res, next){
    let filepath = `/path/to/photos/${req.params.photoId}.jpg`;
    fs.unlink(filepath, (error) =&gt; {
        if(error) return next(error);
        return res.status(200).json({
            message: `Your photo is removed - Photo ID was ${req.params.photoId}`
        });
    });    
}
</code></pre>

<p><em><em>Example</em>: A simple controller that takes a PhotoID and deletes files associated to it</em></p>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>

<p>Some challenges when mocking chained functions:</p>
<ul><li>Stubbing a method, while keeping original callback behavior intact</li></ul>

<h2 id="show-me-the-tests" id="show-me-the-tests">Show me the tests</h2>

<p>From the <em><a href="./how-to-mock-chained-functions">How to mock chained functions</a></em> article, there are three <em>relevant to the current context</em> avenues we leverage for our mocking strategy.</p>

<pre><code class="language-JavaScript">
let outputMock = { ... };
sinon.stub(obj, &#39;func&#39;).returns(outputMock);
sinon.stub(obj, &#39;func&#39;).callsFake(function fake(){ return outputMock; })
let func = sinon.spy(function fake(){ return outputMock; });

</code></pre>

<p>We can put those approaches to test in the following test case</p>

<pre><code class="language-JavaScript">var sinon = require(&#39;sinon&#39;);
var assert = require(&#39;chai&#39;).assert;

// Somewhere in your code. 
it(&#39;#fs:unlink removes a file&#39;, function () {
    this.fs = require(&#39;fs&#39;);
    var func = function(fn){ return fn.apply(this, arguments); };//mocked behaviour 
    
    //Spy + Stubbing fs.unlink function, to avoid a real file removal
    var unlink = sinon.stub(this.fs, &#34;unlink&#34;, func);
    assert(this.fs.unlink.called, &#34;#unlink() has been called&#34;);

    unlink.restore(); //restoring default function 
});
</code></pre>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we established the difference between stub/spy and fake concepts, how they work in concert to deliver effective test doubles, and how to leverage their <em>drop-in-replacement</em> capabilities when testing functions.</p>

<p>Testing tends to be more of art, than a science, practice makes perfect. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li><strong>Evan Hahn</strong> in <em>“<a href="https://evanhahn.com/how-do-i-jasmine/">How do I Jasmine</a>“</em> – has pretty good examples that leverages spies along the way.</li></ul>

<p>tags: <a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-spy-stub-or-fake-a-functions</guid>
      <pubDate>Thu, 17 Jun 2021 06:11:24 +0000</pubDate>
    </item>
    <item>
      <title>How to Stub Promise Function and Mock Resolved Output</title>
      <link>https://getsimple.works/how-to-stub-promise-function-and-mock-resolved-output?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Mocking and Stubbing walk hand in hand. In this blog, we document stubbing functions with promise constructs. The use cases are going to be based on Models. We keep in mind that there is a clear difference between mocking versus stub/spying and using fakes.&#xA;&#xA;In this article we will talk about: &#xA;&#xA;Stub a promise construct by replacing it with a fake &#xA;Stub a promising construct by using third-party tools &#xA;Mocking database-bound input and output  &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;//Lab Pet&#xA;window.fetch(&#39;/full/url/&#39;).then(function(res){ &#xA;    service.doSyncWorkWith(res); &#xA;    return res; &#xA;}).catch(function(err){ &#xA;    return err;&#xA;});&#xA;&#xA;Example:&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;When trying to figure out how to approach stub functions that return a promise, the following points may be a challenge:&#xA;&#xA;How to deal with the asynchronous nature of the promise. &#xA;Making stubs drop-in replacements of some portion of the code block, and leave intact anything else. &#xA;&#xA;The following sections will explore more on making points stated above work. &#xA;&#xA;Content &#xA;&#xA;From Johnny Reeves Blog: Stub the services&#39; Async function, then return mocked response&#xA;&#xA;var sinon = require(&#39;sinon&#39;);&#xA;describe(&#39;#fetch()&#39;, function(){&#xA;    before(function(){ &#xA;        //one way&#xA;        fetchStub = sinon.stub(window, &#39;fetch&#39;).returns(bakedPromise(mockedResponse));&#xA;        //other way&#xA;        fetchStub = sinon.stub(window, &#39;fetch&#39;, function(options){ &#xA;            return bakedPromise(mockedResponse);&#xA;        });&#xA;        //other way&#xA;        fetchStub = sinon.stub(window, &#39;fetch&#39;).resolves(mockedResponse);&#xA;&#xA;    });&#xA;    after(function(){ fetchStub.restore(); });&#xA;    it(&#39;works&#39;, function(){&#xA;        //use default function like nothing happened&#xA;        window.fetch(&#39;/url&#39;);&#xA;        assert(fetchStub.called, &#39;#fetch() has been called&#39;);&#xA;        //or &#xA;        assert(window.fetch.called, &#39;#fetch() has been called&#39;);&#xA;    });&#xA;    it(&#39;fails&#39;, function(){&#xA;            //one way&#xA;        fetchStub = sinon.stub(window, &#39;fetch&#39;, function(options){ &#xA;            return bakedFailurePromise(mockedResponse);&#xA;        });&#xA;        //another way using &#39;sinon-stub-promise&#39;s returnsPromise()&#xA;        //PS: You should install =  npm install sinon-stub-promise&#xA;        fetchStub = sinon.stub(window, &#39;fetch&#39;).returnsPromise().rejects(reasonMessage);&#xA;&#xA;    });&#xA;});&#xA;Example:&#xA;&#xA;bakedPromise() is any function that takes a Mocked(baked) Response and returns a promise      &#xA;This approach doesn&#39;t tell you if Service.doJob() has been expected. For That: &#xA;source&#xA;source&#xA;&#xA;Conclusion&#xA;&#xA;In this article, we established the difference between Promise versus regular callbacks and how to stub promise constructs, especially in database operations context, and replacing them with fakes. Testing tends to be more of art, than science, proactive makes perfect. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book.  &#xA;&#xA;References &#xA;&#xA;Testing nodejs Applications book&#xA;Getting started with nodejs and mocha ~ SemaphoreCI Community Tutorials&#xA;A TDD Approach to Building a Todo API Using nodejs and mongodb ~ SemaphoreCI Community Tutorials&#xA;Evan Hahn in &#34;How do I Jasmine&#34; - has pretty good examples that leverages spies along the way. &#xA;&#xA;tags: #snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>Mocking and Stubbing walk hand in hand. In this blog, we document stubbing functions with promise constructs. The use cases are going to be based on Models. We keep in mind that there is a clear difference between mocking versus stub/spying and using fakes.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Stub a promise construct by replacing it with a fake</li>
<li>Stub a promising construct by using third-party tools</li>
<li>Mocking <em>database-bound</em> input and output<br/></li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<pre><code class="language-JavaScript">
//Lab Pet
window.fetch(&#39;/full/url/&#39;).then(function(res){ 
    service.doSyncWorkWith(res); 
    return res; 
}).catch(function(err){ 
    return err;
});

</code></pre>

<p><em><em>Example</em>:</em></p>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>

<p>When trying to figure out how to approach stub functions that return a promise, the following points may be a challenge:</p>
<ul><li>How to deal with the asynchronous nature of the promise.</li>
<li>Making stubs drop-in replacements of some portion of the code block, and leave intact anything else.</li></ul>

<p>The following sections will explore more on making points stated above work.</p>

<h2 id="content" id="content">Content</h2>
<ul><li>From Johnny Reeves Blog: Stub the services&#39; Async function, then return mocked response</li></ul>

<pre><code class="language-JavaScript">
var sinon = require(&#39;sinon&#39;);
describe(&#39;#fetch()&#39;, function(){
    before(function(){ 
        //one way
        fetchStub = sinon.stub(window, &#39;fetch&#39;).returns(bakedPromise(mockedResponse));
        //other way
        fetchStub = sinon.stub(window, &#39;fetch&#39;, function(options){ 
            return bakedPromise(mockedResponse);
        });
        //other way
        fetchStub = sinon.stub(window, &#39;fetch&#39;).resolves(mockedResponse);

    });
    after(function(){ fetchStub.restore(); });
    it(&#39;works&#39;, function(){
        //use default function like nothing happened
        window.fetch(&#39;/url&#39;);
        assert(fetchStub.called, &#39;#fetch() has been called&#39;);
        //or 
        assert(window.fetch.called, &#39;#fetch() has been called&#39;);
    });
    it(&#39;fails&#39;, function(){
            //one way
        fetchStub = sinon.stub(window, &#39;fetch&#39;, function(options){ 
            return bakedFailurePromise(mockedResponse);
        });
        //another way using &#39;sinon-stub-promise&#39;s returnsPromise()
        //PS: You should install =&gt; npm install sinon-stub-promise
        fetchStub = sinon.stub(window, &#39;fetch&#39;).returnsPromise().rejects(reasonMessage);

    });
});
</code></pre>

<p><em><em>Example</em>:</em></p>
<ul><li><code>bakedPromise()</code> is any function that takes a Mocked(baked) Response and returns a promise<br/></li>
<li>This approach doesn&#39;t tell you if <code>Service.doJob()</code> has been expected. For That:</li>
<li><strong><a href="https://jonnyreeves.co.uk/2012/stubbing-javascript-promises-with-sinonjs/">source</a></strong></li>
<li><strong><a href="https://templecoding.com/blog/2016/02/29/how-to-stub-promises-using-sinonjs/">source</a></strong></li></ul>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we established the difference between Promise versus regular callbacks and how to stub promise constructs, especially in database operations context, and replacing them with fakes. Testing tends to be more of art, than science, proactive makes perfect. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>Getting started with <code>nodejs</code> and <code>mocha</code> ~ <a href="https://semaphoreci.com/community/tutorials/getting-started-with-node-js-and-mocha">SemaphoreCI Community Tutorials</a></li>
<li>A TDD Approach to Building a Todo API Using <code>nodejs</code> and <code>mongodb</code> ~ <a href="https://semaphoreci.com/community/tutorials/a-tdd-approach-to-building-a-todo-api-using-node-js-and-mongodb">SemaphoreCI Community Tutorials</a></li>
<li><strong>Evan Hahn</strong> in <em>“<a href="https://evanhahn.com/how-do-i-jasmine/">How do I Jasmine</a>“</em> – has pretty good examples that leverages spies along the way.</li></ul>

<p>tags: <a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-to-stub-promise-function-and-mock-resolved-output</guid>
      <pubDate>Thu, 17 Jun 2021 06:10:10 +0000</pubDate>
    </item>
    <item>
      <title>How to modularize nodejs applications</title>
      <link>https://getsimple.works/how-to-modularize-nodejs-applications?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[  divide et impera &#xA;&#xA;One of the key issues working with large-scale nodejs applications is the management of complexity. Modularization shifts focus to transform the codebase into reusable, easy-to-test modules. This article explores some techniques used to achieve that.&#xA;&#xA;  This article is more theoretical, &#34;How to make nodejs applications modular&#34; may help with that is more technical. &#xA;&#xA;In this article we will talk about: &#xA;&#xA;Exploration of modularization techniques available within the ecosystem&#xA;Leveraging module.exports or import/export utilities to achieve modularity&#xA;Using the index file to achieve modularity   &#xA;How above techniques can be applied at scale&#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;This piece of code is going to go through modularization in &#34;How to make nodejs applications modular&#34; blog. As for now, we will highlight failures and points of interest down below. &#xA;&#xA;var express = require(&#39;express&#39;);&#xA;var app = express();&#xA;&#xA;/*Data Layer/&#xA;var mongodb = require(&#34;mongodb&#34;);&#xA;mongoose.connect(&#39;mongodb://localhost:27017/devdb&#39;);&#xA;var User = require(&#39;./models&#39;).User; &#xA;&#xA;/*&#xA; Essential Middelewares &#xA; /&#xA;app.use(express.logger());&#xA;app.use(express.cookieParser());&#xA;app.use(express.session({ secret: &#39;angrybirds&#39; }));&#xA;app.use(express.bodyParser());&#xA;app.use((req, res, next) =  { /* Adding CORS support here / });&#xA;&#xA;app.use((req, res) =  res.sendFile(path.normalize(path.join(_dirname, &#39;index.html&#39;))));&#xA;&#xA;/* .. more routes + code for app ... /&#xA;app.get(&#39;/&#39;, function (req, res) {&#xA;  return res.send(&#39;Hello World!&#39;);&#xA;});&#xA;&#xA;/* code that initialize everything, then comes this route/&#xA;app.get(&#39;/users/:id&#39;, function(req, res, next){&#xA;  User.findById(req.params.id, function(error, user){&#xA;    if(error) return next(error);&#xA;    return res.status(200).json(user);&#xA;  });&#xA;});&#xA;&#xA;/*&#xA; More code, more time, more developers &#xA; Then you realize that you actually need:&#xA; / &#xA;app.get(&#39;/admin/:id&#39;, function(req, res, next){&#xA;  User.findById(req.params.id, function(error, user){&#xA;    if(error) return next(error);&#xA;    return res.status(200).json(user);&#xA;  });&#xA;});&#xA;/*&#xA; This would work just fine, but we may also have a requirement to listen to Twitter changes &#xA;app.listen(port, function () {&#xA;  console.log(&#39;Example app listening on port 3000!&#39;)&#xA;});&#xA;/&#xA;&#xA;var server = require(&#39;http&#39;).createServer(app);&#xA;server.listen(app.get(&#39;port&#39;), () =  console.log(Listening on ${ process.env.PORT || 8080 }));&#xA;var wss = require(&#39;socket.io&#39;)(server);&#xA;//Handling realtime data&#xA;wss.on(&#39;connection&#39;(socket, event) =  {&#xA;    socket.on(&#39;error&#39;, () =  {});&#xA;    socket.on(&#39;pong&#39;, () =  {});&#xA;    socket.on(&#39;disconnect&#39;, () =  {});&#xA;    socket.on(&#39;message&#39;, () =  {});&#xA;});&#xA;Example:&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;When trying to navigate strategies around modularization of nodejs applications, the following points may be a challenge:&#xA;&#xA;Where to start with modularization&#xA;How to choose the right modularization technique. &#xA;&#xA;The following sections will explore more on making points stated above work. &#xA;&#xA;Modules &#xA;&#xA;In nodejs context, anything from a variable to function, to classes, or an entire library qualifies to become modules.&#xA;&#xA;A module can be seen as an independent piece of code dedicated to doing one and only one task at a time. The amalgamation of multiple tasks under one abstract task, or one unit of work, is also good module candidates. To sum up, modules come in function, objects, classes, configuration metadata, initialization data, servers, etc.&#xA;&#xA;  Modularization is one of the techniques used to break down a large software into smaller malleable, more manageable components. In this context, a module is treated as the smallest independent composable piece of software, that does only one task. Testing such a unit in isolation becomes relatively easy. Since it is a composable unit, integrating it into another system becomes a breeze.&#xA;&#xA;Leveraging exports&#xA;&#xA;To make a unit of work a module, nodejs exposes import/export, or module.exports/require, utilities. Therefore, modularization is achieved by leveraging the power of module.exports in ES5, equivalent to export in ES7+.  With that idea, the question to &#34;Where to start with modularization?&#34; becomes workable. &#xA;&#xA;Every function, object, class, configuration metadata, initialization data, or the server that can be exported, has to be exported. That is how Leveraging module.exports or import/export utilities to achieve modularity looks like. &#xA;&#xA;After each individual entity becomes exportable, there is a small enhancement that can make importing the entire library, or modules, a bit easier. Depending on project structure, be feature-based or kind-based.&#xA;&#xA;At this point, we may ask ourselves if the technique explained above can indeed scale. Simply put, Can the techniques explained above scale?&#xA;&#xA;  The large aspect of large scale application combines Lines of Code(20k+ LoC), number of features, third party integrations, and the number of people contributing to the project. Since these parameters are not mutually exclusive, a one-person project can also be large scale, it has to have fairly large lines of code involved or a sizable amount of third-party integrations. &#xA;&#xA;nodejs applications, as a matter of fact like any application stack, tend to be big and hard to maintain past a threshold. There is no better strategy to manage complexity than breaking down big components into small manageable chunks.&#xA;&#xA;Large codebases tend to be hard to test, therefore hard to maintain, compared to their smaller counterparts. Obviously, nodejs applications are no exception to this. &#xA;&#xA;Leveraging the index &#xA;&#xA;Using the index file at every directory level makes it possible to load modules from a single instruction. Modules at this point in time, are supposed to be equivalent or hosted in the same directory. Directories can mirror categories(kind) or features, or a mixture of both. Adding the index file at every level makes sure we establish control over divided entities, aka divide and conquer. &#xA;&#xA;  Divide and conquer is one of the old Roman Empire Army techniques to manage complexity. Dividing a big problem into smaller manageable ones, allowed the Roman Army to conquer, maintain and administer a large chunk of the known world in middle age. &#xA;&#xA;Scalability &#xA;&#xA;  How the above techniques can be applied at scale&#xA;&#xA;The last question in this series would be to know if the above-described approach can scale. First, the key to scalability is to build things that do not scale first. Then when scalability becomes a concern, figure out how to address those concerns. So, the first iteration would be supposed to not be scalable. &#xA;&#xA;Since the index is available to every directory, and the index role becomes to expose directory content to the outer world, it doe not matter if the directory count yields 1 or 100 or 1000+. A simple call to the parent directory makes it possible to have access to 1, 100, or 1000+ libraries.&#xA;&#xA;From this vantage point, introduction of the index at every level of the directory comes with scalability as a &#34;cherry on top of the cake&#34;_. &#xA;&#xA;Where to go from here &#xA;&#xA;This post focused on the theoretical side of the modularization business. The next step is to put techniques described therein put to test in the next blog post.&#xA;&#xA;Conclusion&#xA;&#xA;Modularization is a key strategy to crafting reusable composable software components. It brings elegance to the codebase, reduces copy/paste occurrences(DRY), improves performance, and makes the codebase testable. Modularization reduces the complexity associated with large-scale nodejs applications.&#xA;&#xA;In this article, we revisited how to increase key layers testability, by leveraging basic modularization techniques. Techniques discussed in this article, are applicable to other aspects of the nodejs application. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;Export this: Interface Design Patterns for nodejs Modules ~ GoodEggs Blog&#xA;nodejs module patterns using simple examples Darren DeRidder Blog&#xA;Modular nodejs Express ~  StrongLoop Blog&#xA;&#xA;tags: #snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<blockquote><p> <strong>divide et impera</strong></p></blockquote>

<p>One of the key issues working with large-scale <code>nodejs</code> applications is the management of complexity. Modularization shifts focus to transform the codebase into reusable, easy-to-test modules. This article explores some techniques used to achieve that.</p>

<blockquote><p>This article is more theoretical, <em><a href="./how-to-make-nodejs-applications-modular">“How to make <code>nodejs</code> applications modular”</a></em> may help with that is more technical.</p></blockquote>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Exploration of modularization techniques available within the ecosystem</li>
<li>Leveraging <code>module.exports</code> or <code>import</code>/<code>export</code> utilities to achieve modularity</li>
<li>Using the <code>index</code> file to achieve modularity<br/></li>
<li>How above techniques can be applied at scale</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<p>This piece of code is going to go through modularization in <em><a href="./how-to-make-nodejs-applicaition-modular">“How to make <code>nodejs</code> applications modular”</a></em> blog. As for now, we will highlight failures and points of interest down below.</p>

<pre><code class="language-JavaScript">var express = require(&#39;express&#39;);
var app = express();

/**Data Layer*/
var mongodb = require(&#34;mongodb&#34;);
mongoose.connect(&#39;mongodb://localhost:27017/devdb&#39;);
var User = require(&#39;./models&#39;).User; 

/**
 * Essential Middelewares 
 */
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.session({ secret: &#39;angrybirds&#39; }));
app.use(express.bodyParser());
app.use((req, res, next) =&gt; { /** Adding CORS support here */ });

app.use((req, res) =&gt; res.sendFile(path.normalize(path.join(__dirname, &#39;index.html&#39;))));


/** .. more routes + code for app ... */
app.get(&#39;/&#39;, function (req, res) {
  return res.send(&#39;Hello World!&#39;);
});


/** code that initialize everything, then comes this route*/
app.get(&#39;/users/:id&#39;, function(req, res, next){
  User.findById(req.params.id, function(error, user){
    if(error) return next(error);
    return res.status(200).json(user);
  });
});

/**
 * More code, more time, more developers 
 * Then you realize that you actually need:
 */ 
app.get(&#39;/admin/:id&#39;, function(req, res, next){
  User.findById(req.params.id, function(error, user){
    if(error) return next(error);
    return res.status(200).json(user);
  });
});
/**
 * This would work just fine, but we may also have a requirement to listen to Twitter changes 
app.listen(port, function () {
  console.log(&#39;Example app listening on port 3000!&#39;)
});
*/

var server = require(&#39;http&#39;).createServer(app);
server.listen(app.get(&#39;port&#39;), () =&gt; console.log(`Listening on ${ process.env.PORT || 8080 }`));
var wss = require(&#39;socket.io&#39;)(server);
//Handling realtime data
wss.on(&#39;connection&#39;(socket, event) =&gt; {
    socket.on(&#39;error&#39;, () =&gt; {});
    socket.on(&#39;pong&#39;, () =&gt; {});
    socket.on(&#39;disconnect&#39;, () =&gt; {});
    socket.on(&#39;message&#39;, () =&gt; {});
});
</code></pre>

<p><em><em>Example</em>:</em></p>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>

<p>When trying to navigate strategies around modularization of <code>nodejs</code> applications, the following points may be a challenge:</p>
<ul><li>Where to start with modularization</li>
<li>How to choose the right modularization technique.</li></ul>

<p>The following sections will explore more on making points stated above work.</p>

<h2 id="modules" id="modules">Modules</h2>

<p>In <code>nodejs</code> context, anything from a variable to function, to classes, or an entire library qualifies to become modules.</p>

<p>A module can be seen as an independent piece of code dedicated to doing one and only one task at a time. The amalgamation of multiple tasks under one abstract task, or one unit of work, is also good module candidates. To sum up, modules come in function, objects, classes, configuration metadata, initialization data, servers, etc.</p>

<blockquote><p><strong>Modularization</strong> is one of the techniques used to break down a large software into smaller malleable, more manageable components. In this context, a module is treated as the smallest independent composable piece of software, that does only one task. Testing such a unit in isolation becomes relatively easy. Since it is a composable unit, integrating it into another system becomes a breeze.</p></blockquote>

<h2 id="leveraging-exports" id="leveraging-exports">Leveraging <code>exports</code></h2>

<p>To make a unit of work a module, <code>nodejs</code> exposes <code>import</code>/<code>export</code>, or <code>module.exports</code>/<code>require</code>, utilities. Therefore, modularization is achieved by leveraging the power of <code>module.exports</code> in ES5, equivalent to <code>export</code> in ES7+.  With that idea, the question to <em>“Where to start with modularization?”</em> becomes workable.</p>

<p>Every function, object, class, configuration metadata, initialization data, or the server that can be exported, has to be exported. That is how <em>Leveraging <code>module.exports</code> or <code>import</code>/<code>export</code> utilities to achieve modularity</em> looks like.</p>

<p>After each individual entity becomes exportable, there is a small enhancement that can make importing the entire library, or modules, a bit easier. Depending on project structure, be feature-based or kind-based.</p>

<p>At this point, we may ask ourselves if the technique explained above can indeed scale. Simply put, <em>Can the techniques explained above scale?</em></p>

<blockquote><p>The <strong><em>large</em></strong> aspect of <strong><em>large scale</em></strong> application combines Lines of Code(20k+ LoC), number of features, third party integrations, and the number of people contributing to the project. Since these parameters are not mutually exclusive, a one-person project can also be large scale, it has to have fairly large lines of code involved or a sizable amount of third-party integrations.</p></blockquote>

<p><code>nodejs</code> applications, as a matter of fact like any application stack, tend to be big and hard to maintain past a threshold. There is no better strategy to manage complexity than breaking down big components into small manageable chunks.</p>

<p>Large codebases tend to be hard to test, therefore hard to maintain, compared to their smaller counterparts. Obviously, <code>nodejs</code> applications are no exception to this.</p>

<h2 id="leveraging-the-index" id="leveraging-the-index">Leveraging the <code>index</code></h2>

<p>Using the <code>index</code> file at every directory level makes it possible to load modules from a single instruction. Modules at this point in time, are supposed to be equivalent or hosted in the same directory. Directories can mirror categories(kind) or features, or a mixture of both. Adding the index file at every level makes sure we establish control over divided entities, aka divide and conquer.</p>

<blockquote><p><strong><em>Divide and conquer</em></strong> is one of the old Roman Empire Army techniques to manage complexity. Dividing a big problem into smaller manageable ones, allowed the Roman Army to conquer, maintain and administer a large chunk of the known world in middle age.</p></blockquote>

<h2 id="scalability" id="scalability">Scalability</h2>

<blockquote><p>How the above techniques can be applied at scale</p></blockquote>

<p>The last question in this series would be to know if the above-described approach can scale. First, the key to scalability is to build things that do not scale first. Then when scalability becomes a concern, figure out how to address those concerns. So, the first iteration would be supposed to not be scalable.</p>

<p>Since the index is available to every directory, and the index role becomes to expose directory content to the outer world, it doe not matter if the directory count yields 1 or 100 or 1000+. A simple call to the parent directory makes it possible to have access to 1, 100, or 1000+ libraries.</p>

<p>From this <em>vantage point</em>, introduction of the index at every level of the directory comes with scalability as a <em>“cherry on top of the cake”</em>.</p>

<h2 id="where-to-go-from-here" id="where-to-go-from-here">Where to go from here</h2>

<p>This post focused on the theoretical side of the modularization business. The next step is to put techniques described therein <a href="./how-to-make-nodejs-application-modular">put to test in the next blog post</a>.</p>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Modularization is a key strategy to crafting reusable composable software components. It brings elegance to the codebase, reduces copy/paste occurrences(DRY), improves performance, and makes the codebase testable. Modularization reduces the complexity associated with large-scale <code>nodejs</code> applications.</p>

<p>In this article, we revisited how to increase key layers testability, by leveraging basic modularization techniques. Techniques discussed in this article, are applicable to other aspects of the <code>nodejs</code> application. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>Export <code>this</code>: Interface Design Patterns for <code>nodejs</code> Modules ~ <a href="https://bites.goodeggs.com/posts/export-this/">GoodEggs Blog</a></li>
<li><code>nodejs</code> module patterns using simple examples <a href="https://darrenderidder.github.io/talks/ModulePatterns/#/">Darren DeRidder Blog</a></li>
<li>Modular <code>nodejs</code> Express ~  <a href="https://strongloop.com/strongblog/modular-node-js-express/">StrongLoop Blog</a></li></ul>

<p>tags: <a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-to-modularize-nodejs-applications</guid>
      <pubDate>Thu, 17 Jun 2021 05:43:22 +0000</pubDate>
    </item>
    <item>
      <title>Using nginx server on a single domain with multiple IP addresses ~ reverse-proxy mode </title>
      <link>https://getsimple.works/using-nginx-server-on-a-single-domain-with-multiple-ip-addresses?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Is it possible to use one instance of nginx, to serve as a reverse proxy of multiple application servers running on dedicated different IP addresses, under the same domain umbrella?&#xA;&#xA;This article is about pointing in direction on how to achieve that.&#xA;&#xA;  Spoiler: It is possible to run nginx server both as a reverse proxy and load balancer.&#xA;&#xA;In this article we will talk about: &#xA;&#xA;Configure nginx as a nodejs reverse-proxy server &#xA;Proxy multiple IP addresses under the same banner: load balancer&#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Installation&#xA;&#xA;The magic happens at the upstream nodeapps section. This configuration plays the gateway role and makes public a server that was otherwise private. &#xA;&#xA;upstream webupstreams{&#xA;  # Directs to the process with least number of connections.&#xA;  leastconn;&#xA;  server 127.0.0.1:8080 maxfails=0 failtimeout=10s;&#xA;  server localhost:8080 maxfails=0 failtimeout=10s;&#xA;&#xA;  server 127.0.0.1:2368 maxfails=0 failtimeout=10s;&#xA;  server localhost:2368 maxfails=0 failtimeout=10s;&#xA;  keepalive 512;&#xA;&#xA;  keepalive 512;&#xA;}&#xA;&#xA;server {&#xA;  listen 80;&#xA;  servername app.website.tld;&#xA;  clientmaxbodysize 16M;&#xA;  keepalivetimeout 10;&#xA;&#xA;  # Make site accessible from http://localhost/&#xA;  root /var/www/[app-name]/app;&#xA;  location / {&#xA;    proxypass http://webupstreams;&#xA;    proxyhttpversion 1.1;&#xA;    proxysetheader Host $host;&#xA;    proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;    proxysetheader X-Real-IP $remoteaddr;&#xA;  }&#xA;}&#xA;server {&#xA;    listen 80;&#xA;    servername blog.website.tld;&#xA;    accesslog /var/log/blog.website.tld/logs.log;&#xA;    root /var/www/[cms-root-folder|ghost|etc.]&#xA;&#xA;    location / {&#xA;        proxypass http://webupstreams;&#xA;        #proxyhttpversion 1.1;&#xA;        #proxypass http://127.0.0.1:2368;&#xA;        #proxyredirect off;&#xA;&#xA;        proxysetheader X-Real-IP $remoteaddr;&#xA;        proxysetheader HOST $httphost;&#xA;        proxysetheader X-NginX-Proxy true;&#xA;    }&#xA;}&#xA;Example: Typical nginx configuration at /etc/nginx/sites-available/app-name_&#xA;&#xA;  This article is an excerpt from &#34;How to configure nginx as a nodejs application proxy server&#34; article. &#xA;&#xA;Conclusion&#xA;&#xA;In this article, we revisited how to proxy multiple servers via one nginx instance, or nginx load-balancer for short. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;HTTP Load Balancing ~ docs.nginx.com&#xA;How to configure load balancing using nginx&#xA;nginx single domain on multiple ip addresses ~ StackOverflow Question&#xA;&#xA;#snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>Is it possible to use one instance of <code>nginx</code>, to serve as a reverse proxy of multiple application servers running on dedicated different IP addresses, under the same domain umbrella?</p>

<p>This article is about pointing in direction on how to achieve that.</p>

<blockquote><p>Spoiler: It is possible to run <code>nginx</code> server both as a <strong>reverse proxy</strong> and <strong>load balancer</strong>.</p></blockquote>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Configure <code>nginx</code> as a <code>nodejs</code> reverse-proxy server</li>
<li>Proxy multiple IP addresses under the same banner: load balancer</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="installation" id="installation">Installation</h2>

<p>The magic happens at the <code>upstream nodeapps</code> section. This configuration plays the gateway role and makes public a server that was otherwise private.</p>

<pre><code class="language-shell">
upstream webupstreams{
  # Directs to the process with least number of connections.
  least_conn;
  server 127.0.0.1:8080 max_fails=0 fail_timeout=10s;
  server localhost:8080 max_fails=0 fail_timeout=10s;

  server 127.0.0.1:2368 max_fails=0 fail_timeout=10s;
  server localhost:2368 max_fails=0 fail_timeout=10s;
  keepalive 512;

  keepalive 512;
}

server {
  listen 80;
  server_name app.website.tld;
  client_max_body_size 16M;
  keepalive_timeout 10;

  # Make site accessible from http://localhost/
  root /var/www/[app-name]/app;
  location / {
    proxy_pass http://webupstreams;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
server {
    listen 80;
    server_name blog.website.tld;
    access_log /var/log/blog.website.tld/logs.log;
    root /var/www/[cms-root-folder|ghost|etc.]

    location / {
        proxy_pass http://webupstreams;
        #proxy_http_version 1.1;
        #proxy_pass http://127.0.0.1:2368;
        #proxy_redirect off;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;
    }
}
</code></pre>

<p><em><em>Example</em>: Typical <code>nginx</code> configuration at <code>/etc/nginx/sites-available/app-name</code></em></p>

<blockquote><p>This article is an excerpt from <a href="./how-to-configure-nodejs-applications#configure-nginx-to-serve-nodejs-application">“How to configure <code>nginx</code> as a <code>nodejs</code> application proxy server”</a> article.</p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we revisited how to proxy multiple servers via one <code>nginx</code> instance, or <code>nginx</code> load-balancer for short. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li><a href="https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/">HTTP Load Balancing ~ docs.nginx.com</a></li>
<li><a href="https://upcloud.com/community/tutorials/configure-load-balancing-nginx/">How to configure load balancing using <code>nginx</code></a></li>
<li><code>nginx</code> single domain on multiple ip addresses ~ <a href="https://stackoverflow.com/questions/20348930/nginx-single-domain-on-multiple-ip-addresses">StackOverflow Question</a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/using-nginx-server-on-a-single-domain-with-multiple-ip-addresses</guid>
      <pubDate>Thu, 17 Jun 2021 05:22:56 +0000</pubDate>
    </item>
    <item>
      <title>Easy nodejs deployment</title>
      <link>https://getsimple.works/easy-nodejs-deployment?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[This article is going to explore how to deploy a nodejs application on a traditional linux server -- in a non-cloud environment. Even though the use case is Ubuntu, any Linux distro or mac would work perfectly fine. &#xA;&#xA;  For information on deploying on non-traditional servers, read: &#34;Deploying nodejs applications&#34;. For zero-downtime knowledge, read  &#34;How to achieve zero downtime deployment with nodejs&#34; &#xA;&#xA;In this article we will talk about: &#xA;&#xA;Preparing nodejs deployable releases &#xA;Configuring nodejs deployment environment &#xA;Deploying nodejs application on bare metal Ubuntu server &#xA;Switching on nodejs application to be available to the world ~ adding nginx for the reverse proxy to make the application available to the world&#xA;post-deployment support -- production support &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book book, the content can help any software developer to level up their knowledge. You may use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Preparing a deployable release&#xA;&#xA;There are several angles to look at release and deployment from. There are also several ways to release nodejs code, npm and tar for instance, and that depending on the environment in which the code is designed to run. Amongst environments, server-side, universal, or command line are classic examples.&#xA;&#xA;In addition, we have to take a look from a dependency management perspective. Managing dependencies at deployment time has two vectors to take into account: whether the deployment happens on online or offline. &#xA;&#xA;  For the code to be prepared for release, it has to be packaged. Two methods of packaging nodejs software, amongst other things, are managed packaging and bundling. More on this is discussed here&#xA;&#xA;As a plus, versioning should be taken into consideration when preparing a deployable release. The versioning that is a little common circulation is SemVer. &#xA;&#xA;Configuring deployment environment &#xA;&#xA;Before we dive into deployment challenges, let&#39;s look at key software and configuration requirements. &#xA;&#xA;As usual, first-time work can be hard to do. But the yield should be then predictable, flexible to improvement, and capable of being built-upon for future deployments. For context, the deployment environment we are talking about in this section is the production environment.  &#xA;&#xA;Two key configurations are an nginx reverse proxy server and nodejs. But, &#34;Why coupling nodejs server to an nginx reverse proxy server&#34;? The answer to this question is two folds. First, both nodejs and nginx are single-threaded non-blocking reactive systems. Second, the wide adoption of these two tools by the developer community makes it an easy choice, from both influence and availability of collective knowledge the developer community shares via forums/blogs and popular QA sites. &#xA;&#xA;  How to install nginx server ~ there is an article dedicated to this. How to configure nginx as a nodejs application proxy server ~ there is an article dedicated to this. &#xA;&#xA;Additional tools to install and configure may include: mongod database server, redis server, monit for monitoring, upstart for enhancing the init system.&#xA;&#xA;There is a need to better understand the tools required to run nodejs application. It is also our responsibility as developers to have a basic understanding of each tool and the roles it plays in our project, in order to figure out how to configure each tool.&#xA;&#xA;Download source code&#xA;&#xA;Starting from the utility perspective, there is quite a collection of tools that are required to run on the server, alongside our nodejs application. Such software needs to be installed, and updated ~ for patch releases, and upgraded ~ to new major versions to keep the system secure and capable(bug-free/enhanced with new features).&#xA;&#xA;From the packaging perspective, both supporting tools and nodejs applications adhere to a packaging strategy that makes it easy to deploy. When packaging is indeed a bundle, wget/curl can be used to download binaries. When dealing with discoverable packages, npm/yarn/brew can also be used to download our application and its dependencies. Both operation yield same outcomes, which is un-packaging, configuration and installation.&#xA;&#xA;To deploy versioned nodejs application on bare metal Ubuntu server  ~ understanding file system tweaks such as symlink-ing for faster deployments can save time for future deployments.&#xA;&#xA;first time on server side  &#xA;$ apt-get update&#xA;$ apt-get install git&#xA;&#xA;updating|upgrading server side code&#xA;$ apt-get update&#xA;$ apt-get upgrade&#xA;$ brew upgrade &#xA;$ npm upgrade &#xA;&#xA;Package download and installs &#xA;$ /bin/bash -c &#34;$(curl -fsSL https://url.tld/version/install.sh)&#34;&#xA;$ wget -O - https://url.tld/version/install.sh | bash&#xA;&#xA;Discoverable packages &#xA;$ npm install application@next &#xA;$ yarn add application@next &#xA;$ brew install application&#xA;Example: &#xA;&#xA;  The command above can be automated via a scheduled task. Both npm and yarn support the installation of applications bundled in a .tar file. See an example of a simple script source. We have to be mindful to clean up download directories, to save disk space. &#xA;&#xA;Switching on the application &#xA;&#xA;It sounds repetitive, but running npm start does not guarantee the application to be visible outside the metal server box the application is hosted on. This magic belongs to the nginx reverse proxy we were referring to in earlier paragraphs. &#xA;&#xA;A typical nodejs application needs to start one or more of the following services, each time to reboot the application. &#xA;&#xA;symlinking new version to default application path&#xA;$ ln -sfn /var/www/new/version/appname /var/www/appname &#xA;&#xA;$ service nginx restart #nginx|apache server&#xA;$ service redis restart #redis server&#xA;$ service restart mongod #database server in some cases&#xA;$ service appname restart #application itself&#xA;Example:&#xA;&#xA;  PS: Above services are managed with uptime&#xA;&#xA;Adding nginx reverse proxy makes the application available to the outside world. Switching on/off the application can be summarized in one command: service nginx stop. Likewise, to switch off and back on can be issued in one command: service nginx restart.&#xA;&#xA;Post-deployment support &#xA;&#xA;Asynchronous timely tasks can be used to resolve a wide range of issues. Background tasks such as fetching updates from third-party data providers, system health check, and notifications, automated software updates, database cleaning, cache busting, scheduled expensive/CPU intensive batch processing jobs just to name a few. &#xA;&#xA;It is possible to leverage existing asynchronous timely OS-provided tasks processing infrastructure to achieve any of the named use cases, as it is true for third-party tools to do exactly the same job. &#xA;&#xA;Rule of thumb&#xA;&#xA;The following is a mental model that can be applied to the common use cases of releases. It may be basic for DevOps professionals, but useful enough for developers doing some operations work as well. &#xA;&#xA;Prepare deployable releases&#xA;Update and install binaries ~ using apt, brew etc.  &#xA;Download binaries ~ using git,wget, curl or brew&#xA;symlink directories(/log, /config, /app)&#xA;Restart  servers and services ~ redis, nginx, mongodb and app &#xA;When something goes bad ~ walk two steps back. That is our rollback strategy.  &#xA;&#xA;  This model can be refined, to make most of these tasks repeatable and automated, deployments included. &#xA;&#xA;Conclusion &#xA;&#xA;In this article, we revisited quick easy, and most basic nodejs deployment strategies. We also revisited how to expose the deployed applications to the world using nginx as a reverse proxy server. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;How to set up CI/CD Pipeline for a nodejs app with Jenkins ~ Moshe Ezderman - Medium&#xA;&#34;Build your dependencies into your deployable packages&#34;&#xA;&#xA;#snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>This article is going to explore how to deploy a <code>nodejs</code> application on a traditional <code>linux</code> server — in a non-cloud environment. Even though the use case is Ubuntu, any Linux <em>distro</em> or <code>mac</code> would work perfectly fine.</p>

<blockquote><p>For information on deploying on non-traditional servers, read: <strong><em><a href="./deploying-nodejs-application">“Deploying <code>nodejs</code> applications”</a></em></strong>. For zero-downtime knowledge, read  <strong><em><a href="./achieving-nodejs-zero-downtime">“How to achieve zero downtime deployment with <code>nodejs</code>“</a></em></strong></p></blockquote>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Preparing <code>nodejs</code> deployable releases</li>
<li>Configuring <code>nodejs</code> deployment environment</li>
<li>Deploying <code>nodejs</code> application on bare metal Ubuntu server</li>
<li>Switching on <code>nodejs</code> application to be available to the world ~ adding <code>nginx</code> for the reverse proxy to make the application available to the world</li>
<li>post-deployment support — production support</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong> book, the content can help any software developer to level up their knowledge. <strong><em><a href="https://bit.ly/2ZFJytb">You may use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="preparing-a-deployable-release" id="preparing-a-deployable-release">Preparing a deployable release</h2>

<p>There are several angles to look at release and deployment from. There are also several ways to release <code>nodejs</code> code, <code>npm</code> and <code>tar</code> for instance, and that depending on the environment in which the code is designed to run. Amongst environments, server-side, universal, or command line are classic examples.</p>

<p>In addition, we have to take a look from a dependency management perspective. Managing dependencies at deployment time has two vectors to take into account: whether the deployment happens on <strong><em>online</em></strong> or <strong><em>offline</em></strong>.</p>

<blockquote><p>For the code to be prepared for release, it has to be packaged. Two methods of packaging <code>nodejs</code> software, amongst other things, are managed packaging and bundling. <a href="./deploying-nodejs-applications#reducing-friction">More on this is discussed here</a></p></blockquote>

<p>As a plus, versioning should be taken into consideration when preparing a deployable release. The versioning that is a little common circulation is <strong><em>SemVer</em></strong>.</p>

<h2 id="configuring-deployment-environment" id="configuring-deployment-environment">Configuring deployment environment</h2>

<p>Before we dive into deployment challenges, let&#39;s look at key software and configuration requirements.</p>

<p>As usual, first-time work can be hard to do. But the yield should be then predictable, flexible to improvement, and capable of being built-upon for future deployments. For context, the deployment environment we are talking about in this section is the production environment.</p>

<p>Two key configurations are an <code>nginx</code> reverse proxy server and <code>nodejs</code>. But, <em>“Why coupling <code>nodejs</code> server to an <code>nginx</code> reverse proxy server”</em>? The answer to this question is two folds. First, both <code>nodejs</code> and <code>nginx</code> are single-threaded non-blocking reactive systems. Second, the wide adoption of these two tools by the developer community makes it an easy choice, from both influence and availability of collective knowledge the developer community shares via forums/blogs and popular QA sites.</p>

<blockquote><p>How to install <code>nginx</code> server ~ [there is an article dedicated to this](). How to configure <code>nginx</code> as a <code>nodejs</code> application proxy server ~ <a href="./how-to-configure-nodejs-applications#configure-nginx-to-serve-nodejs-application">there is an article dedicated to this</a>.</p></blockquote>

<p>Additional tools to install and configure may include: <code>mongod</code> database server, <code>redis</code> server, <a href="https://mmonit.com/monit/#home"><code>monit</code></a> for monitoring, <a href="http://upstart.ubuntu.com/download.html"><code>upstart</code></a> for enhancing the <code>init</code> system.</p>

<p>There is a need to better understand the tools required to run <code>nodejs</code> application. It is also our responsibility as developers to have a basic understanding of each tool and the roles it plays in our project, in order to figure out how to configure each tool.</p>

<h2 id="download-source-code" id="download-source-code">Download source code</h2>

<p>Starting from the utility perspective, there is quite a collection of tools that are required to run on the server, alongside our <code>nodejs</code> application. Such software needs to be installed, and updated ~ for patch releases, and upgraded ~ to new major versions to keep the system secure and capable(bug-free/enhanced with new features).</p>

<p>From the packaging perspective, both supporting tools and <code>nodejs</code> applications adhere to a packaging strategy that makes it easy to deploy. When packaging is indeed a bundle, <code>wget</code>/<code>curl</code> can be used to download binaries. When dealing with discoverable packages, <code>npm</code>/<code>yarn</code>/<code>brew</code> can also be used to download our application and its dependencies. Both operation yield same outcomes, which is un-packaging, configuration and installation.</p>

<p>To deploy versioned <code>nodejs</code> application on bare metal Ubuntu server  ~ understanding file system tweaks such as symlink-ing for faster deployments can save time for future deployments.</p>

<pre><code class="language-shell">#first time on server side  
$ apt-get update
$ apt-get install git

#updating|upgrading server side code
$ apt-get update
$ apt-get upgrade
$ brew upgrade 
$ npm upgrade 

# Package download and installs 
$ /bin/bash -c &#34;$(curl -fsSL https://url.tld/version/install.sh)&#34;
$ wget -O - https://url.tld/version/install.sh | bash

# Discoverable packages 
$ npm install application@next 
$ yarn add application@next 
$ brew install application
</code></pre>

<p>_<em>Example</em>: _</p>

<blockquote><p>The command above can be automated via a scheduled task. Both <code>npm</code> and <code>yarn</code> support the installation of applications bundled in a <code>.tar</code> file. See an example of a simple script <a href="https://serverfault.com/a/226389">source</a>. We have to be mindful to clean up download directories, to save disk space.</p></blockquote>

<h2 id="switching-on-the-application" id="switching-on-the-application">Switching on the application</h2>

<p>It sounds repetitive, but running <code>npm start</code> does not guarantee the application to be visible outside the metal server box the application is hosted on. This magic belongs to the <code>nginx</code> reverse proxy we were referring to in earlier paragraphs.</p>

<p>A typical <code>nodejs</code> application needs to start one or more of the following services, each time to reboot the application.</p>

<pre><code class="language-shell"># symlinking new version to default application path
$ ln -sfn /var/www/new/version/appname /var/www/appname 

$ service nginx restart #nginx|apache server
$ service redis restart #redis server
$ service restart mongod #database server in some cases
$ service appname restart #application itself
</code></pre>

<p><em><em>Example</em>:</em></p>

<blockquote><p>PS: Above services are managed with <code>uptime</code></p></blockquote>

<p>Adding <code>nginx</code> reverse proxy makes the application available to the outside world. Switching on/off the application can be summarized in one command: <code>service nginx stop</code>. Likewise, to switch off and back on can be issued in one command: <code>service nginx restart</code>.</p>

<h2 id="post-deployment-support" id="post-deployment-support">Post-deployment support</h2>

<p>Asynchronous timely tasks can be used to resolve a wide range of issues. Background tasks such as <em>fetching updates from third-party data providers</em>, <em>system health check, and notifications</em>, <em>automated software updates</em>, <em>database cleaning</em>, <em>cache busting</em>, <em>scheduled expensive/CPU intensive batch processing jobs</em> just to name a few.</p>

<p>It is possible to leverage existing asynchronous timely OS-provided tasks processing infrastructure to achieve any of the named use cases, as it is true for third-party tools to do exactly the same job.</p>

<h2 id="rule-of-thumb" id="rule-of-thumb">Rule of thumb</h2>

<p>The following is a mental model that can be applied to the common use cases of releases. It may be basic for DevOps professionals, but useful enough for developers doing some operations work as well.</p>
<ul><li>Prepare deployable releases</li>
<li>Update and install binaries ~ using <code>apt</code>, <code>brew</code> etc.<br/></li>
<li>Download binaries ~ using <code>git</code>,<code>wget</code>, <code>curl</code> or <code>brew</code></li>
<li><code>symlink</code> directories(<code>/log</code>, <code>/config</code>, <code>/app</code>)</li>
<li>Restart  servers and services ~ <code>redis</code>, <code>nginx</code>, <code>mongodb</code> and <code>app</code></li>
<li>When something goes bad ~ walk two steps back. That is our rollback strategy.<br/></li></ul>

<blockquote><p>This model can be refined, to make most of these tasks repeatable and automated, deployments included.</p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we revisited quick easy, and most basic <code>nodejs</code> deployment strategies. We also revisited how to expose the deployed applications to the world using <code>nginx</code> as a reverse proxy server. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>How to set up CI/CD Pipeline for a <code>nodejs</code> app with Jenkins ~ <a href="https://medium.com/@mosheezderman/how-to-set-up-ci-cd-pipeline-for-a-node-js-app-with-jenkins-c51581cc783c">Moshe Ezderman – Medium</a></li>
<li><a href="https://strongloop.com/strongblog/node-js-deploy-production-best-practice/"><em>“Build your dependencies into your deployable packages”</em></a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/easy-nodejs-deployment</guid>
      <pubDate>Thu, 17 Jun 2021 05:08:19 +0000</pubDate>
    </item>
    <item>
      <title>nodejs infrastructure</title>
      <link>https://getsimple.works/nodejs-infrastructure?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[For practical reasons and ease of maintenance, deploying smaller portions(atomic deployments) to different platforms is one of the strategies to achieve zero-downtime deployments. This article discusses how some portions of a large-scale application, can be deployed to various cloud services, or servers, to keep the service running even some nodes stays down. &#xA;&#xA;In this article we will talk about: &#xA;&#xA;Cloud is somebody else&#39;s servers, therefore can fail&#xA;Plan B: Alternative services to provide when the main server is down &#xA;How to design the application for resiliency, avoid cloud vendor lock-in &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Modern days infrastructure &#xA;&#xA;Cloud and serverless are somebody else&#39;s servers. As long as the server is in the equation, failures that lead to downtimes and whatnot are always going to be there, in one way or another. The price tag associated with running the application on somebody else&#39;s server, versus what it costs to roll out own infrastructure should also come into the picture when talking about nodejs infrastructure.&#xA;&#xA;  For more on cheap infrastructure, visit this github collection about free or cheap platforms good from prototype to beta version of your app. &#xA;&#xA;Since Cloud-native and serverless platforms are servers at their core, meaning: can fail, having a Plan B or alternative services to back up to when the main service is down making a good investment. &#xA;&#xA;To solve the nodejs infrastructure equation, we always have to solve the &#34;how to design the application for resiliency, while at the same time avoiding cloud vendor lock-in&#34; equation.  The good ol&#39; server, hosted on bare-bone metal server, takes time to set up, but solve a whole range of issues while, at the same time, keeping our independence intact. &#xA;&#xA;To compensate, there are some CDN that we can tap into, to get assets faster to the user. The same applies to distributed caching solutions, that can save the main service dollars when paying for traffic. &#xA;&#xA;In any case, it can be a good thing to split code into chunks that can be deployed to different servers. For example, in the case of pictures are hosted on one service(Netlify, etc), the database service(server) can be a completely different platform, and the REST API or messaging service, another.  &#xA;&#xA;  For more on cheap bare-bone server providers, visit this link to make a choice&#xA;&#xA;Conclusion&#xA;&#xA;In this article, we revisited how to achieve cloud vendor lock-in independence, when, at the same time build resilient nodejs applications. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;Features | Netlify ~ Netifly&#xA;Deploy your site through Netlify and add HTTPS, CDN distribution, caching, continuous deployment ~ Netifly&#xA;How to set up CI/CD Pipeline for a node.js app with Jenkins ~ Moshe Ezderman - Medium&#xA;&#xA;#nodejs #cloud #serverless #discuss&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>For practical reasons and ease of maintenance, deploying smaller portions(atomic deployments) to different platforms is one of the strategies to achieve zero-downtime deployments. This article discusses how some portions of a large-scale application, can be deployed to various cloud services, or servers, to keep the service running even some nodes stays down.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Cloud is somebody else&#39;s servers, therefore can fail</li>
<li>Plan B: Alternative services to provide when the main server is down</li>
<li>How to design the application for resiliency, avoid cloud vendor lock-in</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="modern-days-infrastructure" id="modern-days-infrastructure">Modern days infrastructure</h2>

<p>Cloud and <code>serverless</code> are somebody else&#39;s servers. As long as the server is in the equation, failures that lead to downtimes and whatnot are always going to be there, in one way or another. The price tag associated with running the application on somebody else&#39;s server, versus what it costs to roll out own infrastructure should also come into the picture when talking about <code>nodejs</code> infrastructure.</p>

<blockquote><p>For more on cheap infrastructure, visit this <a href="https://github.com/255kb/stack-on-a-budget"><code>github</code> collection about free or cheap platforms</a> good from prototype to beta version of your app.</p></blockquote>

<p>Since Cloud-native and <code>serverless</code> platforms are servers at their core, meaning: can fail, having a <strong><em>Plan B</em></strong> or alternative services to back up to when the main service is down making a good investment.</p>

<p>To solve the <code>nodejs</code> infrastructure equation, we always have to solve the <em>“how to design the application for resiliency, while at the same time avoiding cloud vendor lock-in”</em> equation.  The <em>good ol&#39;</em> server, hosted on <em>bare-bone</em> metal server, <a href="./how-to-configure-nodejs-applications">takes time to set up, but solve a whole range of issues while</a>, at the same time, keeping our independence intact.</p>

<p>To compensate, there are some CDN that we can tap into, to get assets faster to the user. The same applies to distributed caching solutions, that can save the main service dollars when paying for traffic.</p>

<p>In any case, it can be a good thing to split code into chunks that can be deployed to different servers. For example, in the case of pictures are hosted on one service(Netlify, etc), the database service(server) can be a completely different platform, and the REST API or messaging service, another.</p>

<blockquote><p>For more on cheap bare-bone server providers, visit this <a href="https://github.com/255kb/stack-on-a-budget">link to make a choice</a></p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we revisited how to achieve cloud vendor lock-in independence, when, at the same time build resilient <code>nodejs</code> applications. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>Features | Netlify ~ <a href="https://www.netlify.com/features/">Netifly</a></li>
<li>Deploy your site through Netlify and add HTTPS, CDN distribution, caching, continuous deployment ~ <a href="https://www.netlify.com/features/">Netifly</a></li>
<li>How to set up CI/CD Pipeline for a node.js app with Jenkins ~ <a href="https://medium.com/@mosheezderman/how-to-set-up-ci-cd-pipeline-for-a-node-js-app-with-jenkins-c51581cc783c">Moshe Ezderman – Medium</a></li></ul>

<p><a href="https://getsimple.works/tag:nodejs" class="hashtag"><span>#</span><span class="p-category">nodejs</span></a> <a href="https://getsimple.works/tag:cloud" class="hashtag"><span>#</span><span class="p-category">cloud</span></a> <a href="https://getsimple.works/tag:serverless" class="hashtag"><span>#</span><span class="p-category">serverless</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/nodejs-infrastructure</guid>
      <pubDate>Thu, 17 Jun 2021 05:00:22 +0000</pubDate>
    </item>
    <item>
      <title>Objectives ~ testing nodejs applications</title>
      <link>https://getsimple.works/objectives-testing-nodejs-applications?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Building, testing, deploying, and maintaining large-scale applications is challenging in many ways. It takes discipline, structure, and rock-solid processes to succeed with production-ready nodejs applications. This document put together a collection of ideas and tribulations from a personal perspective so that you can avoid some mistakes and succeed with your project.&#xA;&#xA;In this article we will talk about: &#xA;&#xA;Avoiding integration test trap &#xA;Mocking strategically or applying code re-usability to mocks&#xA;Achieve a healthy test coverage&#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Why &#xA;&#xA;There is a lot of discussion around Unit testing. Developers don&#39;t like testing, only the testing approach differs from one person to another, from one system to the next one. It is also worth highlighting that some, if not the majority, skip TDD&#39;s way of doing business for alternatives. One thing is clear: You cannot guarantee the sanity of a piece of code unless it is tested. The &#34;HOW&#34; may be the problem we have to figure out and fix. In other words, should a test be carried out before or after writing the code?  &#xA;&#xA;Pro: Tests(Unit tests)&#xA;&#xA;Increases confidence when releasing new versions. &#xA;Increases confidence when changing the code, such as during refactoring exercises. &#xA;Increase overall code health, and reduces bug count&#xA;Helps new developers to the project better understand the code &#xA;&#xA;Cons:&#xA;&#xA;Takes time to write, refactor and maintain &#xA;Increases codebase learning curve&#xA;&#xA;What &#xA;&#xA;There is a consensus that every feature should be tested before landing in a production environment. Since tests tend to be repetitive, and time-consuming, it makes sense to automate the majority of the tests, if not all. Automation makes it feasible to run regression tests on quite a large codebase and tends to be more accurate and effective than manually testing alone. &#xA;&#xA;Layers that require particular attention while testing are: &#xA;&#xA;Unit test controllers&#xA;Unit test business logic(services) and domain (models)&#xA;Utility library&#xA;Server start/stop/restart and anything in between those states   &#xA;Testing routes(integration testing)&#xA;Testing secured routes&#xA;&#xA;  Questions we should keep in our mind while testing is: How to create good test cases? (Case   Feature   Expectations ) and How to unit test controllers, and avoid test to be integration tests&#xA;&#xA;The beauty of having nodejs, or JavaScript in general, is that to some extent, some test cases can be reusable for back-end and for front-end code as well. Like any other component/module, unit test code should be refactored for better structure, readability than the rest of the codebase.&#xA;&#xA;Choosing Testing frameworks&#xA;&#xA;For those who bought in the idea of having a TDD way of doing business, here are a couple of things to consider when choosing a testing framework:&#xA;&#xA;Learning curve&#xA;How easy to integrate into project/existing testing frameworks&#xA;How long does it take to debug testing code&#xA;How good is the documentation &#xA;How good is the community backing the testing framework, and how well the library happens to be maintained&#xA;How test doubles (Spies, Mocking, Coverage reports, etc) work within the framework. Third-party test doubles tend to beat framework native test doubles. &#xA;&#xA;Conclusion&#xA;&#xA;In this article, we revisited high-level objectives when testing a nodejs application deployable at scale. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book that dives deeper into integration testing trap and how to avoid it, how to achieve a healthy code coverage without breaking the piggy bank, as well as some thoughts on mocking strategically. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;&#xA;#snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>Building, testing, deploying, and maintaining large-scale applications is challenging in many ways. It takes discipline, structure, and rock-solid processes to succeed with production-ready <code>nodejs</code> applications. This document put together a collection of ideas and tribulations from a personal perspective so that you can avoid some mistakes and succeed with your project.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Avoiding integration test trap</li>
<li>Mocking strategically or applying code re-usability to mocks</li>
<li>Achieve a healthy test coverage</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="why" id="why">Why</h2>

<p>There is a lot of discussion around Unit testing. Developers don&#39;t like testing, only the testing approach differs from one person to another, from one system to the next one. It is also worth highlighting that some, if not the majority, skip TDD&#39;s way of doing business for alternatives. One thing is clear: You cannot guarantee the sanity of a piece of code unless it is tested. The “HOW” may be the problem we have to figure out and fix. In other words, should a test be carried out <strong>before</strong> or <strong>after</strong> writing the code?</p>

<p><strong>Pro</strong>: Tests(Unit tests)</p>
<ul><li>Increases confidence when releasing new versions.</li>
<li>Increases confidence when changing the code, such as during refactoring exercises.</li>
<li>Increase overall code health, and reduces bug count</li>
<li>Helps new developers to the project better understand the code</li></ul>

<p><strong>Cons</strong>:</p>
<ul><li>Takes time to write, refactor and maintain</li>
<li>Increases codebase learning curve</li></ul>

<h2 id="what" id="what">What</h2>

<p>There is a consensus that every feature should be tested before landing in a production environment. Since tests tend to be repetitive, and time-consuming, it makes sense to automate the majority of the tests, if not all. Automation makes it feasible to run regression tests on quite a large codebase and tends to be more accurate and effective than manually testing alone.</p>

<p>Layers that require particular attention while testing are:</p>
<ul><li>Unit test controllers</li>
<li>Unit test business logic(services) and domain (models)</li>
<li>Utility library</li>
<li>Server start/stop/restart and anything in between those states<br/></li>
<li>Testing routes(integration testing)</li>
<li>Testing secured routes</li></ul>

<blockquote><p>Questions we should keep in our mind while testing is: <em><strong>How to create good test cases? (Case &gt; Feature &gt; Expectations )</strong></em> and <em><strong>How to unit test controllers, and avoid test to be integration tests</strong></em></p></blockquote>

<p>The beauty of having <code>nodejs</code>, or JavaScript in general, is that to some extent, some test cases can be reusable for back-end and for front-end code as well. Like any other component/module, unit test code should be refactored for better structure, readability than the rest of the codebase.</p>

<h2 id="choosing-testing-frameworks" id="choosing-testing-frameworks">Choosing Testing frameworks</h2>

<p>For those who bought in the idea of having a TDD way of doing business, here are a couple of things to consider when choosing a testing framework:</p>
<ul><li>Learning curve</li>
<li>How easy to integrate into project/existing testing frameworks</li>
<li>How long does it take to debug testing code</li>
<li>How good is the documentation</li>
<li>How good is the community backing the testing framework, and how well the library happens to be maintained</li>
<li>How test doubles (Spies, Mocking, Coverage reports, etc) work within the framework. Third-party test doubles tend to beat framework native test doubles.</li></ul>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we revisited high-level objectives when testing a <code>nodejs</code> application deployable at scale. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book that dives deeper into <strong><em>integration testing trap</em></strong> and how to avoid it, how to achieve a healthy code coverage without breaking the piggy bank, as well as some thoughts on mocking strategically.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/objectives-testing-nodejs-applications</guid>
      <pubDate>Thu, 17 Jun 2021 04:37:17 +0000</pubDate>
    </item>
    <item>
      <title>Test Doubles ~ How do jasmine/jest/mocha/chai and sinon stack-up</title>
      <link>https://getsimple.works/test-doubles-how-do-jasmine-jest-mocha-chai-and-sinon-stack-up?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In the real world, jargon is sometimes confusing to the point some words may lose their intended meaning to some audiences. This blog re-injects clarity on some misconceptions around testing jargon.&#xA;&#xA;In this article we will talk about: &#xA;&#xA;Confusing technical terms around testing tools &#xA;Confusing technical terms around testing strategies &#xA;How to easily remember &#34;which is what&#34; around testing tools&#xA;How to easily remember &#34;which is what&#34; around test strategies&#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover &#xA;&#xA;Show me the code&#xA;&#xA;//order/model.js&#xA;Order.find()&#xA;&#x9;.populate()&#xA;&#x9;.sort()&#xA;&#x9;.exec(function(err, order){ &#xA;        /* ... /&#xA;    });&#xA;&#xA;//order/middleware.js&#xA;new Order(params).save((error, order, next) =  {&#xA;    if(error) return next(error, null);&#xA;    new OrderService(order).scheduleShipping();&#xA;    return next(null, order);&#xA;});&#xA;Example: Used to showcase test double usage&#xA;&#xA;Asking the right questions&#xA;&#xA;When trying to figure out the &#34;what does what&#34; with testing stacks, the following questions gives a clue on how to differentiate one concept from the next and one tool from the next:&#xA;&#xA;  This article is unfinished business and will be adding more content as I gather more confusing terms, or find some more interesting use cases.  &#xA;&#xA;What role does the test runner play when testing the code sample above&#xA;What role does the test doubles play when testing the code sample above &#xA;How do a test runner and test doubles stack up in this particular use case. &#xA;How do Stubbing differ from Mocking&#xA;How to Stubbing differs from Spy fakes ~ (functions with pre-programmed behavior that replace real behaviors)  &#xA;How can we tell the function next(error, obj) has been called with  -- order or error arguments in our case?&#xA;What are other common technical terms that cause confusion around test strategies -- Things such as unit test, integration test and end to end tests. Other less common, but confusing anyways, terms like smoke testing, exploratory testing, regression testing, performance testing, benchmarking, and the list goes on. We have to make an inventory of these terms(alone or in a team, and formulate a definition around each one before we adopt using them vernacular day-to-day communication).  &#xA;What are other common technical terms that cause confusion around testing tools -- which tools are more likely to cause confusion, and how do they stack up in our test cases (test double tools: mocking tools, spying tools, stubbing tools versus frameworks such as mocha chai sinon jest jasmine etc)&#xA;How to easily remember which is what terms around test strategies such as unit/regression/integration/smoke/etc tests&#xA;How to easily remember which is what terms around testing tools such as mocks/stubs/fakes/spies/etc tools.&#xA;&#xA;  In the test double universe, there is a clear distinction between a stub, a fake, a mock, and a spy. The stub is a drop-in replacement of a function or method we are not willing to run when testing a code block. A Mock, on the other hand, is a drop-in replacement of an object, most of the time used when data encapsulated in an object is expensive to get. The object can either be just data, or instance of a class, or both. A spy tells us when a function has been called, without necessarily replacing a function. A fake and a stub are pretty close relatives, and both replace function implementations. &#xA;&#xA;Conclusion &#xA;&#xA;In this blog, we explored differentiations around test strategies and testing tools. Without prescribing a solution, we let our thoughts play with possibilities around solutions and strategies that we can adapt for various use cases and projects.  &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;jasmine vs. mocha, chai, and sinon&#xA;&#xA;#snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>In the real world, jargon is sometimes confusing to the point some words may lose their intended meaning to some audiences. This blog re-injects clarity on some misconceptions around testing jargon.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Confusing technical terms around testing tools</li>
<li>Confusing technical terms around testing strategies</li>
<li>How to easily remember <em>“which is what”</em> around testing tools</li>
<li>How to easily remember <em>“which is what”</em> around test strategies</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<pre><code class="language-JavaScript">//order/model.js
Order.find()
	.populate()
	.sort()
	.exec(function(err, order){ 
        /** ... */
    });

//order/middleware.js
new Order(params).save((error, order, next) =&gt; {
    if(error) return next(error, null);
    new OrderService(order).scheduleShipping();
    return next(null, order);
});
</code></pre>

<p><em><em>Example</em>: Used to showcase test double usage</em></p>

<h2 id="asking-the-right-questions" id="asking-the-right-questions">Asking the right questions</h2>

<p>When trying to figure out the <em>“what does what”</em> with testing stacks, the following questions gives a clue on how to differentiate one concept from the next and one tool from the next:</p>

<blockquote><p>This article is unfinished business and will be adding more content as I gather more confusing terms, or find some more interesting use cases.</p></blockquote>
<ul><li>What role does the test runner play when testing the code sample above</li>
<li>What role does the test doubles play when testing the code sample above</li>
<li>How do a test runner and test doubles stack up in this particular use case.</li>
<li>How do Stubbing differ from Mocking</li>
<li>How to Stubbing differs from Spy fakes ~ (functions with pre-programmed behavior that replace real behaviors)<br/></li>
<li>How can we tell the function <code>next(error, obj)</code> has been called with  — <code>order</code> or <code>error</code> arguments in our case?</li>
<li>What are other common technical terms that cause confusion around test strategies — Things such as <em>unit test</em>, <em>integration test</em> and <em>end to end tests</em>. Other less common, but confusing anyways, terms like <em>smoke testing</em>, <em>exploratory testing</em>, <em>regression testing</em>, <em>performance testing</em>, <em>benchmarking</em>, and the list goes on. We have to make an inventory of these terms(alone or in a team, and formulate a definition around each one before we adopt using them vernacular day-to-day communication).<br/></li>
<li>What are other common technical terms that cause confusion around testing tools — which tools are more likely to cause confusion, and how do they stack up in our test cases (test double tools: mocking tools, spying tools, stubbing tools versus frameworks such as <code>mocha</code> <code>chai</code> <code>sinon</code> <code>jest</code> <code>jasmine</code> etc)</li>
<li>How to easily remember <em>which is what</em> terms around test strategies such as unit/regression/integration/smoke/etc tests</li>
<li>How to easily remember <em>which is what</em> terms around testing tools such as mocks/stubs/fakes/spies/etc tools.</li></ul>

<blockquote><p>In the test double universe, there is a clear distinction between a stub, a fake, a mock, and a spy. The stub is a drop-in replacement of a function or method we are not willing to run when testing a code block. A Mock, on the other hand, is a drop-in replacement of an object, most of the time used when data encapsulated in an object is expensive to get. The object can either be just data, or instance of a class, or both. A spy tells us when a function has been called, without necessarily replacing a function. A fake and a stub are pretty close relatives, and both replace function implementations.</p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this blog, we explored differentiations around test strategies and testing tools. Without prescribing a solution, we let our thoughts play with possibilities around solutions and strategies that we can adapt for various use cases and projects.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li><a href="https://thejsguy.com/2015/01/12/jasmine-vs-mocha-chai-and-sinon.html"><code>jasmine</code> vs. <code>mocha</code>, <code>chai</code>, and <code>sinon</code></a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/test-doubles-how-do-jasmine-jest-mocha-chai-and-sinon-stack-up</guid>
      <pubDate>Thu, 17 Jun 2021 04:21:56 +0000</pubDate>
    </item>
  </channel>
</rss>