-
Notifications
You must be signed in to change notification settings - Fork 3
/
atom.xml
770 lines (653 loc) · 61.2 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[smartcode ltd]]></title>
<link href="http://smartcodeltd.github.io/atom.xml" rel="self"/>
<link href="http://smartcodeltd.github.io/"/>
<updated>2015-09-10T19:46:09+01:00</updated>
<id>http://smartcodeltd.github.io/</id>
<author>
<name><![CDATA[Jan Molak]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Communicating build status better with Jenkins and the Build Monitor plugin]]></title>
<link href="http://smartcodeltd.github.io/blog/2014/10/16/communicating-build-status-better-with-jenkins-and-the-build-monitor-plugin/"/>
<updated>2014-10-16T17:21:49+01:00</updated>
<id>http://smartcodeltd.github.io/blog/2014/10/16/communicating-build-status-better-with-jenkins-and-the-build-monitor-plugin</id>
<content type="html"><![CDATA[<p>If you’re doing continuous integration chances are that you also care
about your team understanding the current state of your project.
Maybe you use a lava lamp or some other fancy device to visualise whether your
builds are red or green.
Or perhaps you’ve got my little <a href="https://github.com/jan-molak/jenkins-build-monitor-plugin">Build Monitor plugin</a>
installed on your Jenkins box and displayed on some shared screen for your team to see?</p>
<p>Most visual extreme feedback devices use similar representation of the build status
– the well-known <a href="http://en.wikipedia.org/wiki/Traffic_light_rating_system">RAG rating</a> used in a traffic light system.
Now, what does this RAG rating mean and how will it be interpreted by your team?
Yes, I know that you understand how the traffic lights work, but bear with me for just a moment
and maybe this short article will help you to avoid the bad case of rotting builds.</p>
<!-- more -->
<p><strong>RAG</strong> stands for <strong>R</strong>ed, <strong>A</strong>mber and <strong>G</strong>reen.</p>
<p><strong>Green</strong> is simple – it indicates that everything is OK:
your tests have passed,
deployment succeeded,
an artifact has been correctly produced and it matches your quality criteria,
this sort of thing. Basically it’s safe for the traffic to proceed and for you to introduce new awesome features.</p>
<p><strong>Red</strong> is also pretty straight-forward – one of the above is not the case. The traffic should stop.
Perhaps your tests have failed? Or maybe your CI server couldn’t promote the artifact
for some reason? One way or another, red means that something didn’t go according to plan
and someone should look into it <em>immediately</em>.</p>
<p><strong>Amber</strong> – now that’s the one I have a problem with…</p>
<h2>The bad case of rotting builds</h2>
<p>In Jenkins, amber represents an <em>unstable</em> build.
OK, but first, what does <em>unstable</em> mean according to the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Terminology">Jenkins terminology</a>?</p>
<blockquote><p>A build is unstable if it was built successfully and one or more publishers report it unstable. For example if the JUnit publisher is configured and a test fails then the build will be marked unstable.</p><footer><strong>Jenkins Terminology</strong> <cite>Table of Terms Used in Jenkins</cite></footer></blockquote>
<p>And here’s the trouble, you see? To me if a test has failed, it means that either the software I help building
no longer behaves as expected or the test case no longer reflects what the desired behaviour is.
Both scenarios should be reflected in a broken, red build, and a red build should result in me stopping whatever new features
I was adding and fixing what’s broken first.</p>
<p>Another trouble with using amber to represent builds with failing tests is that
humans are optimistic by nature<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> – amber simply doesn’t look as bad in the status report
as red so you can get away with it for longer.</p>
<p>I’ve seen development teams ignoring <em>unstable</em> builds for weeks and even months because
“they were not <em>really</em> broken”,
“only had <em>a few</em> flaky tests”
and
“[those failing tests] were not <em>that</em> important anyway”.
On several occasions I’ve worked with teams that started with accepting a small percentage of their tests failing as “normal and to be expected”.
Over time, however, this small percentage became 10%, then 15% then 50%, eventually ignoring test failures got them to a stage where those poor chaps
started to question the point of automated testing altogether.</p>
<p>If you’re using Jenkins to run automated tests I strongly encourage you to consider the <a href="http://en.wikipedia.org/wiki/Broken_windows_theory">Broken Windows Theory</a>,
fail the build when the tests fail and make sure you fix those failures as soon as you learn about them.</p>
<p>OK, so why have I <a href="http://bit.ly/JBMBuild132">recently introduced</a> a visual representation of an <em>unstable</em> build to the <a href="https://github.com/jan-molak/jenkins-build-monitor-plugin">Build Monitor plugin</a>?
I’ve done it after a <a href="https://github.com/jan-molak/jenkins-build-monitor-plugin/issues/9">long conversation</a> with the Build Monitor plugin community because…</p>
<h2>Not all Jenkins jobs are created equal</h2>
<p>… and not all of them execute automated tests. Consider a Jenkins job gathering static code analysis metrics for example. Let’s take test coverage for argument’s sake.</p>
<p>For some development teams this metric falling below say 80% is an important problem that needs to be addressed immediately (a red build).
Other teams prefer to shoo before they shoot: use amber to indicate the metric falling below the required, ideal level
(<em>the coverage has decreased, we should look into it when we have a moment</em>)
and distinguish it from it falling below say 50% (<em>did someone ignore all the tests again?</em>)
so that they can prioritise their work better.</p>
<p>Remember however that even in the above scenario, if you leave your <em>unstable</em> builds all by themselves for too long,
they will rot and cause you trouble when least expected<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>.</p>
<p>Happy green builds!</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:1">
<p>to all the pessimist out there – here’s the research done by the University of Kansas and Gallup ;) – <a href="http://www.sciencedaily.com/releases/2009/05/090524122539.htm">People By Nature Are Universally Optimistic, Study Shows</a><a href="#fnref:1" rev="footnote">↩</a></p></li>
<li id="fn:2">
<p>I’m sure you know of the <a href="http://www.murphys-laws.com/murphy/murphy-true.html">Murphy’s law</a><a href="#fnref:2" rev="footnote">↩</a></p></li>
</ol>
</div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Mocking JavaScript a little - test doubles with sinon.js, mocha and chai]]></title>
<link href="http://smartcodeltd.github.io/blog/2014/07/22/mocking-javascript-a-little-test-doubles-with-sinonjs-mocha-and-chai/"/>
<updated>2014-07-22T22:10:57+01:00</updated>
<id>http://smartcodeltd.github.io/blog/2014/07/22/mocking-javascript-a-little-test-doubles-with-sinonjs-mocha-and-chai</id>
<content type="html"><![CDATA[<p>How do you write a test in which you cannot (or chose not to) use real dependencies of whatever is that you’re testing?
What are your options in JavaScript? And what does a test doubles library give you that plain-old-js can’t?
Interested to find out? Read on!</p>
<!--more-->
<h2>System under test</h2>
<p>Let’s assume we have a situation similar to the one described by Uncle Bob Martin in “The Little Mocker”<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.</p>
<p>We have a <code>System</code>:</p>
<figure class='code'><figcaption><span>src/system.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="s1">'use strict'</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * @constructor</span>
</span><span class='line'><span class="cm"> * @param {Authoriser} authoriser</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">System</span><span class="p">(</span><span class="nx">authoriser</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="cm">/** @private */</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">login_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="cm">/** @public */</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">login</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">username</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="nx">authoriser</span><span class="p">.</span><span class="nx">authorise</span><span class="p">(</span><span class="nx">username</span><span class="p">,</span> <span class="nx">password</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'> <span class="o">++</span><span class="nx">login_count</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="cm">/** @public */</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">loginCount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="k">return</span> <span class="nx">login_count</span><span class="p">;</span>
</span><span class='line'> <span class="p">};</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>that delegates the process of logging users in to the <code>Authoriser</code>, which implementation might look more or less like this:</p>
<figure class='code'><figcaption><span>src/authoriser.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="s1">'use strict'</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/** @constructor */</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">Authoriser</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * @public</span>
</span><span class='line'><span class="cm"> *</span>
</span><span class='line'><span class="cm"> * @param {String} username</span>
</span><span class='line'><span class="cm"> * @param {String} password</span>
</span><span class='line'><span class="cm"> *</span>
</span><span class='line'><span class="cm"> * @returns {Boolean}</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'><span class="nx">Authoriser</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">authorise</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">username</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// connects to LDAP or some database, verifies user credentials</span>
</span><span class='line'> <span class="c1">// returns true if the username/password pair is valid, false otherwise</span>
</span><span class='line'> <span class="c1">// ...</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>
<h2>A dummy</h2>
<p>How can we prove that a newly created <code>System</code> has no logged in users?
And do we even need to construct a real <code>Authoriser</code> object for that?</p>
<p>Since we know that calling <code>system.loginCount</code> does not even touch the <code>authoriser</code> object,
we can replace the <code>authoriser</code> with <strong>a dummy</strong>:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A newly created System'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">var</span> <span class="nx">dummy_authoriser</span> <span class="o">=</span> <span class="p">{</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'has no logged in users'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">dummy_authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>And that’s all there is to a dummy! You pass it into something when you have to provide an argument,
but you know that it will never be used.</p>
<h2>A stub</h2>
<p>Let’s now suppose that you want to test a part of your <code>System</code> that requires you to be logged in.</p>
<p>Of course you might say that you could <em>just log in</em>, but you’ve already tested that login works,
and since the process of logging in takes time, why do it twice? Also, if there’s a bug in login your test
would fail too! That’s an unnecessary coupling that can be easily avoided with <strong>a stub</strong>:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System with a logged in user'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">var</span> <span class="nx">accepting_authoriser</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">authorise</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'has a loginCount of 1'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">accepting_authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>So what does this stubbed <code>accepting_authoriser</code> do? It returns true, therefore accepting any username/password pairs.</p>
<p>If you now wanted to test another part of your system that handles unauthorised users you could create a <code>rejecting_authoriser</code> like this:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">rejecting_authoriser</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">authorise</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>
<p>So that’s a stub, it simply returns a value and has no other logic in it.</p>
<blockquote><p>Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test.</p><footer><strong>Martin Fowler</strong> <cite>Test Double</cite></footer></blockquote>
<p>Beautiful! So nice and simple, isn’t it? Just one line of code! Isn’t duck typing brilliant?
Imagine how much more code you’d have to write if you were using Java or C#!
You’d probably have to create an <code>Authoriser</code> interface in the first place,
then make sure both the real implementation and your stub <code>implement</code> that <code>interface</code>, then …</p>
<p>Oh yeah, the <code>interface</code>… We don’t have this construct in JavaScript, do we?</p>
<p>The trouble with using plain-old-js for hand-rolling your test stubs
is that you won’t get a meaningful error when the interface of the stubbed-out object changes
and your test stubs are no longer correct. In worst case scenario you might not even get an error at all!</p>
<p>What could be the consequences of this, you may ask?
Well, I’ve seen huge test suites pass even though the application they were supposed to test was fundamentally broken
as half the code didn’t even exist anymore… Trust me, you don’t want to be there<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> :–)</p>
<p>Right, so this situation is not cool, but can we do better than that? Yes we can! Enter sinon.js<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup>!</p>
<p>How would the <code>accepting_authoriser</code> look implemented with sinon then?</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System with a logged in user'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">var</span> <span class="nx">accepting_authoriser</span> <span class="o">=</span> <span class="nx">sinon</span><span class="p">.</span><span class="nx">createStubInstance</span><span class="p">(</span><span class="nx">Authoriser</span><span class="p">);</span>
</span><span class='line'> <span class="nx">accepting_authoriser</span><span class="p">.</span><span class="nx">authorise</span><span class="p">.</span><span class="nx">returns</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'has a loginCount of 1'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">accepting_authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>And what makes it different? Calling <code>sinon.createStubInstance(Authoriser)</code> creates a stub object
that allows you to stub out only those methods that exist on the <code>prototype</code> of the original <code>Authoriser</code>.</p>
<p>Now that’s important because it means that should the <code>#authorise</code> method happily decide to change its
name to say <code>#isAuthorised</code> one day, you’d get a <code>TypeError</code> <em>in your test</em>,
exactly where you attempt to stub out the no longer existing <code>#authorise</code>. Cool, right?</p>
<h2>A spy</h2>
<p>Do you remember when I said in the beginning that <code>System</code>
delegates the process of logging users in to the <code>Authoriser</code>?
How can we test whether or not this interaction really takes place?
What we’d need to do is spy on the caller to see inside the workings of the algorithm we’re testing –
and that’s precisely what <strong>spies</strong> are for<sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup>:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">accepting_authoriser_spy</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">authorise_was_called</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">authorise</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">authorise_was_called</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">afterEach</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">accepting_authoriser_spy</span><span class="p">.</span><span class="nx">authorise_was_called</span> <span class="o">=</span> <span class="kc">false</span>
</span><span class='line'> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'delegates logging users in to the authoriser'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">accepting_authoriser_spy</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">accepting_authoriser_spy</span><span class="p">.</span><span class="nx">authorise_was_called</span><span class="p">).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>You inject a spy object in exactly the same way you’d inject a stub, but then at the end of your test
you check if the interactions recorded by your spy are the ones you expected it to see.</p>
<blockquote><p>Spies are stubs that also record some information based on how they were called.</p><footer><strong>Martin Fowler</strong> <cite>Test Double</cite></footer></blockquote>
<p>Another thing to note is that
because a spy maintains state (<code>authorise_was_called</code> flag in this example), it needs to be reset between the tests
to avoid one test case affecting another – this is done in the <code>afterEach</code> block.</p>
<p>Of course our hand-rolled implementation suffers from the problems I described earlier when we talked
about hand-rolling stubs. Let’s improve our previous implementation with sinon:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">accepting_authoriser</span> <span class="o">=</span> <span class="nx">sinon</span><span class="p">.</span><span class="nx">createStubInstance</span><span class="p">(</span><span class="nx">Authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">accepting_authoriser</span><span class="p">.</span><span class="nx">authorise</span><span class="p">.</span><span class="nx">returns</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">afterEach</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">accepting_authoriser</span><span class="p">.</span><span class="nx">authorise</span><span class="p">.</span><span class="nx">restore</span><span class="p">();</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'delegates logging users in to the authoriser'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">accepting_authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">accepting_authoriser</span><span class="p">.</span><span class="nx">authorise</span><span class="p">).</span><span class="nx">to</span><span class="p">.</span><span class="nx">have</span><span class="p">.</span><span class="nx">been</span><span class="p">.</span><span class="nx">called</span><span class="p">;</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>Similarly to the stub example, I’m also using <code>sinon.createStubInstance</code> here.</p>
<p>There’s one significant difference between our hand-rolled spy implementation and the one above though:
<strong>sinon spy</strong> itself is not the main object you inject, it’s a <strong>wrapper around object’s method</strong>.
That’s why I inject the <code>accepting_authoriser</code> but perform the assertion on <code>accepting_authoriser.authorise</code> spy and
use <code>accepting_authoriser.authorise.restore()</code> to reset it.</p>
<p>Additionally, the fact that sinon spy is a wrapper means that if you wanted to spy
on the real <code>Authoriser's</code> method you could do it like so:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">authoriser</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Authoriser</span><span class="p">(),</span>
</span><span class='line'> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">authoriser</span><span class="p">),</span>
</span><span class='line'> <span class="nx">authorise_spy</span> <span class="o">=</span> <span class="nx">sinon</span><span class="p">.</span><span class="nx">spy</span><span class="p">(</span><span class="nx">authoriser</span><span class="p">,</span> <span class="s1">'authorise'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">expect</span><span class="p">(</span><span class="nx">authorise_spy</span><span class="p">).</span><span class="nx">to</span><span class="p">.</span><span class="nx">have</span><span class="p">.</span><span class="nx">been</span><span class="p">.</span><span class="nx">called</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>
<h2>A mock</h2>
<blockquote><p>A mock is not so interested in the return values of functions.<br/>It’s more interested in what function were called, with what arguments, when, and how often.</p><footer><strong>Robert Martin (Uncle Bob)</strong> <cite>The Little Mocker</cite></footer></blockquote>
<p>Another thing that makes a mock<sup id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup> different from a stub is its <code>verify</code> method,
which groups all the assertions and performs them at the end of a test, verifying our <code>System's</code> <strong>behaviour</strong>:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">accepting_authoriser_mock</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">authorise_was_called</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">authorise</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">authorise_was_called</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">verify</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">authorise_was_called</span><span class="p">).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'delegates logging users in to the authoriser'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">accepting_authoriser_mock</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">accepting_authoriser_mock</span><span class="p">.</span><span class="nx">verify</span><span class="p">();</span> <span class="c1">// assertions moved to #verify</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>Now that we understand how mocks work and we know how to build them ourselves,
let’s see how sinon can make things easier. There’s an essential distinction we need to make
before diving into sinon mocks though:</p>
<blockquote><p>In Sinon, the basic unit of faking is functions, always functions.<br/>So a “stub object” in Java-type literature translates to a “stub function/method” in Sinon/JavaScript land.</p><footer><strong>Christian Johansen</strong> <cite>“Test Spies, Stubs and Mocks - Part 1.5”</cite></footer></blockquote>
<p>… and same goes for sinon mocks. OK, but what does this mean to you? Let’s have a look at differences in the implementation first:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">authoriser</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Authoriser</span><span class="p">(),</span>
</span><span class='line'> <span class="nx">mock</span> <span class="o">=</span> <span class="nx">sinon</span><span class="p">.</span><span class="nx">mock</span><span class="p">(</span><span class="nx">authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">afterEach</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">mock</span><span class="p">.</span><span class="nx">restore</span><span class="p">();</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'delegates logging users in to the authoriser'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// prepare</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// expect</span>
</span><span class='line'> <span class="nx">mock</span><span class="p">.</span><span class="nx">expects</span><span class="p">(</span><span class="s1">'authorise'</span><span class="p">).</span><span class="nx">once</span><span class="p">().</span><span class="nx">returns</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// act</span>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// assert</span>
</span><span class='line'> <span class="nx">mock</span><span class="p">.</span><span class="nx">verify</span><span class="p">();</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>An important thing to note here is that sinon mock is created as a wrapper around
an instance of the <strong>real</strong> <code>Authoriser</code>, but instead of the mock we’re injecting the already mentioned <strong>real</strong> instance
into the <code>System</code>.</p>
<p>This strategy might be problematic if instantiation of your depended-on object (<code>Authoriser</code> in our example)
is expensive; If that’s the case you might want to avoid calling the constructor directly by using <code>Object.create</code><sup id="fnref:6"><a href="#fn:6" rel="footnote">6</a></sup>:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">authoriser</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">Authoriser</span><span class="p">.</span><span class="nx">prototype</span><span class="p">),</span>
</span><span class='line'> <span class="nx">mock</span> <span class="o">=</span> <span class="nx">sinon</span><span class="p">.</span><span class="nx">mock</span><span class="p">(</span><span class="nx">authoriser</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>Note: At the time of writing sinon.js (version 1.10.3) does not provide any equivalent of <code>createStubInstance</code>
for mocks.</p>
<h2>A fake</h2>
<blockquote><p>Fake has business behavior. You can drive a fake to behave in different ways by giving it different data.</p><footer><strong>Robert Martin (Uncle Bob)</strong> <cite>The Little Mocker</cite></footer></blockquote>
<p>Suppose we wanted to define several personas to whom our <code>System</code> responded differently.
Let’s say “bob” knows his password and “alice” forgot it; My personal recommendation
would be to use two separate stubs, but let’s talk about fakes as some might prefer to use them instead:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">fake_authoriser</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">authorise</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">username</span><span class="p">,</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">return</span> <span class="p">(</span><span class="nx">username</span> <span class="o">===</span> <span class="s1">'bob'</span> <span class="o">&&</span> <span class="nx">password</span> <span class="o">===</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">fake_authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'allows Bob in'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'does not allow Alice in'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'alice'</span><span class="p">,</span> <span class="s1">'password'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>… and you could also achieve the same result with sinon:</p>
<figure class='code'><figcaption><span>spec/system.spec.js</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">'A System'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">fake_authoriser</span> <span class="o">=</span> <span class="nx">sinon</span><span class="p">.</span><span class="nx">createStubInstance</span><span class="p">(</span><span class="nx">Authoriser</span><span class="p">);</span>
</span><span class='line'> <span class="nx">fake_authoriser</span><span class="p">.</span><span class="nx">authorise</span>
</span><span class='line'> <span class="p">.</span><span class="nx">returns</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
</span><span class='line'> <span class="p">.</span><span class="nx">withArgs</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">).</span><span class="nx">returns</span><span class="p">(</span><span class="kc">true</span><span class="p">),</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">system</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">System</span><span class="p">(</span><span class="nx">fake_authoriser</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'allows Bob in'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'bob'</span><span class="p">,</span> <span class="s1">'SecretPassword'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">it</span><span class="p">(</span><span class="s1">'does not allow Alice in'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">system</span><span class="p">.</span><span class="nx">login</span><span class="p">(</span><span class="s1">'alice'</span><span class="p">,</span> <span class="s1">'password'</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">expect</span><span class="p">(</span><span class="nx">system</span><span class="p">.</span><span class="nx">loginCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>Be very careful with fakes as they can quickly become <strong>extremely</strong> complicated.
If you can use stubs instead – please do. If you can’t then perhaps
it just highlighted that the thing you’re trying to test is too complex and needs breaking down?</p>
<h2>Tools</h2>
<p>Techniques described in this article can be applied to both front-end and back-end (node.js) development,
same applies to tools I used in the above examples, namely:</p>
<ul>
<li><a href="http://visionmedia.github.io/mocha/">mocha</a> – a popular JavaScript test framework</li>
<li><a href="http://sinonjs.org/">sinon.js</a> – test doubles library</li>
<li><a href="http://chaijs.com/">chai.js</a> and its <a href="http://chaijs.com/api/bdd/">bdd-style</a> assertion library</li>
<li><a href="https://github.com/domenic/sinon-chai">sinon-chai</a> – sinon.js assertions for chai</li>
</ul>
<h2>Final thoughts and a word of warning</h2>
<p>Bear in mind that the more you spy and mock, the tighter you couple your tests to the implementation of your system.
This leads to fragile tests that may break for reasons that shouldn’t break them.</p>
<p>Test doubles should be used with care and applied only when they’re the best tool for the task at hand.
Just like with any other tool in your development tool belt: don’t use a screwdriver to knock in a nail just
because you got a new screwdriver and want to try it out ;–)</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:1">
<p><a href="http://blog.8thlight.com/uncle-bob/2014/05/14/TheLittleMocker.html">The Little Mocker</a> blog post by Uncle Bob Martin. As you might have already noticed, Uncle Bob’s post has inspired this article greatly!<a href="#fnref:1" rev="footnote">↩</a></p></li>
<li id="fn:2">
<p>If you already <em>are</em> in this situation <a href="http://smartcodeltd.github.io/contact">get in touch</a>, I can help you to get out of it :–) OK, no more cheeky marketing. Get back to the article, quick, quick:<a href="#fnref:2" rev="footnote">↩</a></p></li>
<li id="fn:3">
<p><a href="http://sinonjs.org/">Sinon.js</a> was written by Christian Johansen, author of <a href="http://www.amazon.co.uk/gp/product/0321683919/ref=as_li_ss_tl?ie=UTF8&camp=1634&creative=19450&creativeASIN=0321683919&linkCode=as2&tag=smartcode-21">this excellent book</a><a href="#fnref:3" rev="footnote">↩</a></p></li>
<li id="fn:4">
<p>To better understand what spies and other test doubles are and how to use them I highly recommend reading <a href="http://www.amazon.co.uk/gp/product/0131495054/ref=as_li_ss_tl?ie=UTF8&camp=1634&creative=19450&creativeASIN=0131495054&linkCode=as2&tag=smartcode-21">this book</a><a href="#fnref:4" rev="footnote">↩</a></p></li>
<li id="fn:5">
<p>The concept of “mock objects” was originally introduced by Tim Mackinnon, Steve Freeman and Philip Craig in their paper <a href="http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF">Endo-Testing: Unit Testing with Mock Objects</a>. Steve Freeman is a co-author of <a href="http://www.amazon.co.uk/gp/product/0321503627/ref=as_li_ss_tl?ie=UTF8&camp=1634&creative=19450&creativeASIN=0321503627&linkCode=as2&tag=smartcode-21">the GOOSE book</a>. Again, highly recommended.<a href="#fnref:5" rev="footnote">↩</a></p></li>
<li id="fn:6">
<p>Object.create is well documented on <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">MDN</a><a href="#fnref:6" rev="footnote">↩</a></p></li>
</ol>
</div>
]]></content>
</entry>
</feed>