<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>Tinned Fruit</title>
  
  <link href="http://tinnedfruit.com/" />
  <updated>2013-03-05T07:32:56+00:00</updated>
  <id>http://tinnedfruit.com/</id>
  <author>
    <name>Jim Newbery</name>
    <email>james@tinnedfruit.com</email>
  </author>
  
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/tinnedfruit" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="tinnedfruit" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
      <title>Futuristic progressive enhancement talk</title>
      <link href="http://tinnedfruit.com/2012/02/03/futuristic-progressive-enhancement-talk.html" />
      <updated>2012-02-03T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2012/02/03/futuristic-progressive-enhancement-talk</id>
      <content type="html">&lt;p&gt;&lt;a href='http://drewneil.com/'&gt;Drew (The Voice) Neil&lt;/a&gt; and myself were invited to talk about our contrasting views on progressive enhancement at &lt;a href='http://refreshedinburgh.org/'&gt;Refresh Edinburgh&lt;/a&gt; this week. It was my privilege to defend progressive enhancement&amp;#8217;s honour with a talk about why it is still a relevant approach, and how it fits in to the current reality of device variety, fragmented support, and constant innovation. You can &lt;a href='https://vimeo.com/38016394'&gt;watch the video&lt;/a&gt;, &lt;a href='http://speakerdeck.com/u/froots/p/futuristic-progressive-enhancement'&gt;see the slides on Speaker Deck&lt;/a&gt; or grab a &lt;a href='http://dl.dropbox.com/u/6983841/futuristic-progressive-enhancement.pdf'&gt;PDF of the slides with notes&lt;/a&gt; (22.8Mb download).&lt;/p&gt;
&lt;a href='http://speakerdeck.com/u/froots/p/futuristic-progressive-enhancement' rel='external'&gt;&lt;img src='http://images.tinnedfruit.com/blog/20120203/futuristic-progressive-enhancement.jpg' /&gt;&lt;/a&gt;</content>
    </entry>
  
    <entry>
      <title>Your mobile mileage may vary</title>
      <link href="http://tinnedfruit.com/2012/01/11/your-mobile-mileage-may-vary.html" />
      <updated>2012-01-11T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2012/01/11/your-mobile-mileage-may-vary</id>
      <content type="html">&lt;p&gt;If 2012 is definitely, finally, absolutely going to be the year that mobile web takes off, then it seems to have made a good start, with lots of people talking about buying physical devices for testing. All this was started by &lt;a href='http://www.quirksmode.org'&gt;Peter Paul Koch&amp;#8217;s&lt;/a&gt; excellent &lt;a href='http://www.alistapart.com/articles/smartphone-browser-landscape/'&gt;summary on A List Apart&lt;/a&gt; and Stephanie Rieger&amp;#8217;s &lt;a href='http://stephanierieger.com/a-plea-for-progressive-enhancement/'&gt;timely reminder&lt;/a&gt; that mobile device emulators are no match for testing on real devices, illustrated by &lt;a href='http://www.barackobama.com/'&gt;Mr. Obama&amp;#8217;s&lt;/a&gt; magical disappearing navigation. This prompted me to ask for shopping advice on the &lt;a href='http://tech.groups.yahoo.com/group/mobile-web/message/820'&gt;Yahoo Mobile Web group&lt;/a&gt;, which in turn inspired Brad Frost to post a very handy &lt;a href='http://bradfrostweb.com/blog/mobile/test-on-real-mobile-devices-without-breaking-the-bank/'&gt;breakdown of some suggested devices&lt;/a&gt; on his blog.&lt;/p&gt;

&lt;p&gt;Brad&amp;#8217;s list is great, but &lt;a href='http://storify.com/stephaniehobson/if-you-were-buying-5-devices-to-do-mobile-testing?awesm=sfy.co_U2g&amp;amp;utm_campaign=&amp;amp;utm_medium=sfy.co-twitter&amp;amp;utm_source=t.co&amp;amp;utm_content=storify-pingback%5D'&gt;conversations on Twitter&lt;/a&gt;, &lt;a href='http://bagcheck.com/blog/22-mobile-device-testing-the-gear'&gt;Bagcheck lists&lt;/a&gt; and &lt;a href='http://mytestsuite.tumblr.com/'&gt;Stuart Robson&amp;#8217;s newly forged Tumblr&lt;/a&gt; show that everyone&amp;#8217;s test device collection is different. What is suitable for you will depend on the projects you work on and their intended audience.&lt;/p&gt;

&lt;h2 id='do_your_own_research'&gt;Do your own research&lt;/h2&gt;

&lt;p&gt;Before you jump in and buy an arbitrarily list of devices, take some time to find out what your target audience are using. Check your own site analytics, look at the &lt;a href='http://gs.statcounter.com/'&gt;StatCounter&lt;/a&gt; figures for the relevant regions, and see if there is other geographically focused research available. For example, in the UK, &lt;a href='http://www.tecmark.co.uk/uk-mobile-stats-2011'&gt;Tecmark&lt;/a&gt; publish some figures about mobile web twice yearly.&lt;/p&gt;

&lt;p&gt;As an example of regional differences, compare StatCounter&amp;#8217;s figures for BlackBerry market share in the &lt;a href='http://gs.statcounter.com/#mobile_os-US-monthly-201110-201112-bar'&gt;US&lt;/a&gt; (8%) and the &lt;a href='http://gs.statcounter.com/#mobile_os-GB-monthly-201110-201112-bar'&gt;UK&lt;/a&gt; (32%) for October to December 2011. You might decide that, for a UK audience, it is more important to test with BlackBerry devices than a site which is primarily aimed at the US market. On the other hand, the &lt;a href='http://www.tecmark.co.uk/wp-content/uploads/2011/08/Mobile-and-UK-Web-Traffic-August-2011.pdf'&gt;latest Tecmark report&lt;/a&gt; (PDF link) for the UK indicates that BlackBerry devices are only responsible for 3.5% of mobile web traffic, and around 0.5% of all web traffic, belying their apparent market share.&lt;/p&gt;

&lt;p&gt;A little more digging around will give you some rough figures for penetration of individual OS versions, which is also useful in understanding which test devices will be representative. For example, here is a &lt;a href='http://us.blackberry.com/developers/choosingtargetos.jsp'&gt;breakdown of BlackBerry subscribers by OS version&lt;/a&gt; as of August 2011. Google Analytics will give you a breakdown of OS version usage figures for Android and Windows Phone (but not other platforms), and there are some handy up-to-date &lt;a href='http://developer.android.com/resources/dashboard/platform-versions.html'&gt;global figures on the Android developer site&lt;/a&gt;. iOS version penetration figures are harder to come by as Apple don&amp;#8217;t publish figures themselves, but Chitika do publish &lt;a href='http://insights.chitika.com/2011/iphone-ipad-users-front-runners-in-ios5-update/'&gt;occasional iOS version penetration stats&lt;/a&gt;, although their methodology is not clear.&lt;/p&gt;

&lt;h2 id='finding_out_about_devices'&gt;Finding out about devices&lt;/h2&gt;

&lt;p&gt;Market share and analytics will start to give you an idea of where you need to focus your testing efforts. However, it is all very well getting an idea of which OS versions and platforms are likely to be used to access your site. Unless you know the mobile device market inside out, you won&amp;#8217;t know which phones run which exact version of OS, and at what point in the version history significant changes where made to the built-in browser.&lt;/p&gt;

&lt;p&gt;Fortunately, much of this knowledge is available too, in various places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DeviceAtlas has a very handy tool for filtering devices based on various properties, including OS version, form factor, and even feature support. This will allow you to see which HTC devices run &lt;a href='http://deviceatlas.com/resourcecentre/Explore+DeviceAtlas+Data/Data+Explorer#_/filter/877430/1787644/true/0/877430/877437/2.2/1/19/21/240/0/19/20/320/0'&gt;Android 2.2 with a 320 x 240 screen&lt;/a&gt;, for example, although the data is not always fully complete and up to date.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;I also find &lt;a href='http://wikipedia.org'&gt;Wikipedia&lt;/a&gt; to be pretty detailed and as well as the usual specifications, &lt;a href='http://en.wikipedia.org/wiki/Htc_hero'&gt;device pages&lt;/a&gt; contain information about when and where devices were marketed, predecessor and successor models, model variations and other esoteric information that is hard to find elsewhere.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The device manufacturers themselves have varying degrees of info. &lt;a href='http://www.developer.nokia.com/Devices/Device_specifications'&gt;Nokia&amp;#8217;s developer site&lt;/a&gt; has a particularly good model breakdown, for example. I won&amp;#8217;t name names, but some other manufacturers&amp;#8217; sites are, well, not so good.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;a href='http://caniuse.com'&gt;When Can I Use&lt;/a&gt; and PPK&amp;#8217;s &lt;a href='http://www.quirksmode.org/'&gt;Quirksmode&lt;/a&gt; both have browser capability charts so you can see which phones are likely to support which fancy new HTML5 API.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='shopping'&gt;Shopping&lt;/h2&gt;

&lt;p&gt;This is one for those based in the UK.&lt;/p&gt;

&lt;p&gt;We are fortunate enough to have an extremely fluid second-hand mobile market in the UK. There are many unlocked phones, and pay-as-you-go data-only SIMs can be obtained from providers like &lt;a href='http://giffgaff.com/'&gt;GiffGaff&lt;/a&gt; for free if you need them.&lt;/p&gt;

&lt;p&gt;Buying second phones here is pretty easy, and not that expensive, especially when looking for older models. January is also a great time to buy as people are offloading their old phones after Christmas, so prices go down by about 10-20%.&lt;/p&gt;

&lt;p&gt;Because of this, &lt;a href='http://www.ebay.co.uk/'&gt;eBay&lt;/a&gt; is chock full of phones to buy, and with the new pricing trends tools is a pretty handy research tool in its own right. Hours can be lost.&lt;/p&gt;

&lt;p&gt;There are also the dedicated second-hand shops such as &lt;a href='http://www.ineedamobile.com/'&gt;I Need a Mobile&lt;/a&gt;, who sell phones according to a quality grade, tend to be a bit more expensive than the eBay going rate, and don&amp;#8217;t provide chargers.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s worth taking a look at the high street shops, such as &lt;a href='http://www.carphonewarehouse.com/'&gt;Carphone Warehouse&lt;/a&gt;, just to see if there are any special deals on newer sim-free phones, and to get an idea on pricing. Finally, there are the classified ad sites such as &lt;a href='http://www.preloved.co.uk/'&gt;Preloved&lt;/a&gt; and &lt;a href='http://www.gumtree.com/'&gt;GumTree&lt;/a&gt;, both of which have plenty of second hand listings.&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;If you want to boost your mobile and responsive web design testing process, then real devices will make a big difference, not only for catching bugs, but to gain exposure to different design approaches, input methods and form factors. It pays to spend some time researching what would make a representative collection of devices that reflects your target audience, but also appropriately samples from these variations.&lt;/p&gt;

&lt;h2 id='massive_disclaimer'&gt;Massive disclaimer&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m new to all this myself. I recently started focusing more on mobile web development, and I have never been a huge mobile phone fanatic in the past. Until recently, my own collection was limited to an iPhone 3GS and an old Nokia 3210 that I found at the bottom of a drawer. Please, comment if you have anything to add.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Edinburgh International Book Festival mobile site</title>
      <link href="http://tinnedfruit.com/2011/09/08/edinburgh-international-book-festival-mobile-site.html" />
      <updated>2011-09-08T00:00:00+01:00</updated>
      <id>http://tinnedfruit.com/2011/09/08/edinburgh-international-book-festival-mobile-site</id>
      <content type="html">&lt;img class='no-shadow' src='http://images.tinnedfruit.com/blog/20110908/eibf-screengrabs.png' /&gt;
&lt;p&gt;Having seen &lt;a href='/2011/05/10/culture-hack-scotland-2011.html'&gt;my efforts&lt;/a&gt; at the &lt;a href='http://culturehackscotland.com/'&gt;Culture Hack Scotland&lt;/a&gt; event in May, I was approached by the nice people at the &lt;a href='http://www.edbookfest.co.uk/'&gt;Edinburgh International Book Festival&lt;/a&gt; to create an official mobile application for the event, which took place last month.&lt;/p&gt;

&lt;p&gt;The final website can be seen at &lt;a href='http://m.edbookfest.co.uk'&gt;m.edbookfest.co.uk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We decided that a mobile web site would serve the Book Festival&amp;#8217;s needs better than would native applications. Here&amp;#8217;s why we came to that decision, and how building an interactive and responsive mobile website need not be as huge a departure from traditional web development as you might think.&lt;/p&gt;

&lt;h2 id='why_a_mobile_website'&gt;Why a mobile website?&lt;/h2&gt;

&lt;p&gt;In the very first meeting with Andrew Coulton from the festival, we discussed whether it would be better to develop native applications for specific smartphones, or to create a mobile web site. The goal of the app was to provide event listings, information about the authors appearing at the events, and the opportunity to purchase books and e-books through affiliate links to Amazon and iTunes.&lt;/p&gt;

&lt;p&gt;The decision to develop a mobile website was influenced by a number of things, not least that &lt;a href='http://www.zerply.com/profile/froots'&gt;my own background&lt;/a&gt; is in developing websites. This obvious bias aside, there were still plenty of compelling reasons to choose the web approach for the festival.&lt;/p&gt;

&lt;h3 id='no_app_stores'&gt;No app stores&lt;/h3&gt;

&lt;p&gt;Firstly, as an application for a specific event, there was a hard deadline of the start of the festival. The last thing we wanted was to have the launch delayed while awaiting approval from app stores. Website hosting and deployment (using &lt;a href='http://heroku.com'&gt;Heroku&lt;/a&gt;) were entirely under our own control and publication was not subject to approval from a third party platform provider.&lt;/p&gt;

&lt;p&gt;This meant that two or three releases were possible during the festival to fix some bugs, with a very quick turnaround that would not have been possible with native applications.&lt;/p&gt;

&lt;h3 id='the_problem_of_discoverability'&gt;The problem of discoverability&lt;/h3&gt;

&lt;p&gt;Many mobile web applications can suffer from a lack of discoverability. Where app stores provide a single, searchable, centralised directory for native applications, there is no single directory for mobile web applications, although such things do exist.&lt;/p&gt;

&lt;p&gt;However, this is really only a problem for applications that have a broad and varied target audience, such as games and to do lists (and yes, fart apps).&lt;/p&gt;

&lt;p&gt;For a mobile website, it is largely up to the site provider to promote and market their own content through appropriate channels, as is the case for any website. For the Book Festival, we knew that we would have a ready-made engaged audience – the festival-goers themselves. We would also have some marketing channels to target this audience, including the physical festival site, the &lt;a href='http://www.edbookfest.co.uk'&gt;existing desktop website&lt;/a&gt; and the &lt;a href='https://twitter.com/edbookfest'&gt;festival Twitter account&lt;/a&gt;, each which could publicise and link to the mobile site in its own way.&lt;/p&gt;

&lt;p&gt;So, for a specific, targeted and already engaged audience, discoverability becomes far less of an issue. Both native and web applications would have to be promoted in channels targeted to your audience in similar ways, as no global app store is able to target niche users in this way. Discovering a niche application about a specific event through all the noise of highly popular games and gimmicks is not easy.&lt;/p&gt;

&lt;h3 id='interactive_phone_features'&gt;Interactive phone features&lt;/h3&gt;

&lt;p&gt;Some smartphone features can only be accessed via native APIs that are not as yet accessible to mobile web browsers, including cameras, microphones, telephony and so on. If you are creating an app that needs to access these features, then a native app is the way to go for now until broad browser support is available.&lt;/p&gt;

&lt;p&gt;However, many content providers will simply not have any need to use these features. As part of our decision making process, we brainstormed a number of ideas for the application and found that there were none that could not be executed via existing browser technologies.&lt;/p&gt;

&lt;p&gt;For example, one idea that did not make it to the final site was the ability to have an author &amp;#8216;sign&amp;#8217; your smartphone and send the signature image to an email address. This is entirely possible using the HTML5 canvas element, a cross-platform JavaScript library for touch events, and some server-side code to handle sending the email. It is important to have an understanding of how each proposed feature would be supported, even if that feature doesn&amp;#8217;t make the first cut of the application.&lt;/p&gt;

&lt;h3 id='device_support'&gt;Device support&lt;/h3&gt;

&lt;p&gt;The native app approach requires that the developer either create custom apps for each target platform, or uses tools such as &lt;a href='http://www.phonegap.com/'&gt;PhoneGap&lt;/a&gt; to build so-called &amp;#8216;hybrid&amp;#8217; apps - essentially native applications developed using HTML, CSS, JavaScript and a toolkit that provides access to native APIs.&lt;/p&gt;

&lt;p&gt;However, it is platform and the ubiquity of web browsers that makes the web universal, not the technologies that are used to build it. Hybrid apps are distributed and marketed just like other native apps, and so are not intrinsically cross-platform. There is also the chance that APIs will change or new devices will emerge, bringing further problems of interoperability.&lt;/p&gt;

&lt;p&gt;Building a website using agreed web standards and with techniques such as progressive enhancement gives access, in principal, to anyone using a phone with a web browser. The devil here is in the details of browser support and designing a responsive interface to work across a broad spectrum of devices, screen dimensions, interaction capabilities and network performance. As for any website, the devices and browsers you develop for depends on the audience being targeted. Bryan Rieger provides an &lt;a href='http://yiibu.com/articles/rethinking-the-mobile-web/'&gt;excellent dissection of the challenges of cross-device mobile web development&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the case of the Edinburgh Book Festival site, &lt;a href='http://www.tecmark.co.uk/uk-mobile-stats-2011'&gt;statistics&lt;/a&gt; suggest that UK mobile internet use is dominated by the iPhone, iPad, Android devices and Blackberries, with around 5-6% remaining for other devices, even if &lt;a href='http://www.comscore.com/Press_Events/Press_Releases/2011/4/In_Europe_Apple_iOS_Ecosystem_Twice_the_Size_of_Android_When_Accounting_for_Mobile_Phones_Tablets_and_Other_Connected_Media_Devices'&gt;other statistics&lt;/a&gt; suggest these devices do not have as high an overall penetration as you might expect.&lt;/p&gt;

&lt;h3 id='libraries_and_frameworks'&gt;Libraries and frameworks&lt;/h3&gt;

&lt;p&gt;The explosion of tools, libraries and frameworks for mobile web development in recent years means that it is easier than ever to get a head start in mobile web development and minimise time spent ensuring the site works across a wide range of devices.&lt;/p&gt;

&lt;p&gt;It is increasingly the case that many of the modern smartphones are using similar browser technologies – the WebKit rendering engine powers Mobile Safari for iOS, the Android browser, and the Blackberry browser. An experimental WebKit-based browser is even shipped with the Amazon Kindle. Many libraries and frameworks are beginning to target WebKit alone, with some superficial support for other browsers.&lt;/p&gt;

&lt;p&gt;However, the danger here is that, depending on your target audience, you lock out users of other browsers. Other browsers are popular in other audiences, not least Opera Mini. Again, this can be largely avoided by starting with a simple design, a fully operational website, and then layering on enhanced features progressively.&lt;/p&gt;

&lt;h2 id='design_and_development'&gt;Design and development&lt;/h2&gt;

&lt;h3 id='agile_methods'&gt;Agile methods&lt;/h3&gt;

&lt;p&gt;Throughout the design and development of the site, I worked within two-week iteration cycles, with regular deployments to a staging environment, allowing frequent reviews by stakeholders at the festival. All code was written with a test-driven approach using tools such as &lt;a href='http://cukes.info/'&gt;Cucumber&lt;/a&gt;, &lt;a href='https://github.com/jnicklas/capybara'&gt;Capybara&lt;/a&gt;, &lt;a href='http://relishapp.com/rspec'&gt;RSpec&lt;/a&gt; and &lt;a href='http://pivotal.github.com/jasmine/'&gt;Jasmine BDD&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All features were planned in advance using story cards that were agreed and prioritised. This allowed us to keep in touch with what exactly would be delivered in time for the start of the festival, given a fairly rigid budget and timescale. Inevitably not all the ideas could be implemented for this year&amp;#8217;s festival, but with any luck we&amp;#8217;ll be adding features in future years.&lt;/p&gt;

&lt;p&gt;The overall effect of this was that I was able to spread the work of developing the site evenly over a period of 2-3 months, with 3 hours work a day in addition to my &lt;a href='http://tv.sky.com/'&gt;day-to-day work&lt;/a&gt;. Deployment had been continuous, so there were no nerves about the final deployment the night before the festival as there would have been with a Big Launch approach.&lt;/p&gt;

&lt;h3 id='design__keeping_it_simple'&gt;Design - keeping it simple&lt;/h3&gt;

&lt;p&gt;Time and time again during the design and development of the site I found myself up against the constraints of designing for mobile devices. Far from being restrictive, these challenging constraints can be the fuel for innovation and creativity. For example, limited screen real estate forces a focus on supporting the primary user task at hand and the continual stripping away of unnecessary fluff.&lt;/p&gt;

&lt;p&gt;In native applications, this has resulted in some clever interactions that make the most of multi-touch, gestures and accelerometer motions to move features off screen but retain their availability. Some of these have become almost conventional, such as pulling the screen down to refresh a timeline feed.&lt;/p&gt;

&lt;p&gt;I was initially tempted to introduce some touch interactions to the interface, but soon realised that this would have been a mistake.&lt;/p&gt;

&lt;p&gt;Firstly, anything beyond the simplest touch interaction is complex to implement across different devices, and the JavaScript touch libraries that are available can be rather heavy. The interactions themselves are usually not as smooth as they are for native applications.&lt;/p&gt;

&lt;p&gt;Secondly, I expected that few people would discover them – users are consciously using a mobile-optimised website and not a native application, so it is unlikely that they would expect complex touch gestures.&lt;/p&gt;

&lt;p&gt;Instead I aimed to create a design that would be as responsive and simple as possible based on simple single touch interactions. The key here was fast page transitions and optimised performance.&lt;/p&gt;

&lt;h3 id='framework_choice'&gt;Framework choice&lt;/h3&gt;

&lt;p&gt;The mobile web development landscape is now well populated with JavaScript frameworks that allow for rapid development of single-page, touch-optimised web applications. I have spent some time experimenting with these, including &lt;a href='http://jquerymobile.com/'&gt;jQuery Mobile&lt;/a&gt;, &lt;a href='http://jqtouch.com/'&gt;jqTouch&lt;/a&gt; and &lt;a href='http://www.sencha.com/products/touch/'&gt;Sencha Touch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To my mind, all three frameworks are attempting to ape the native experience too closely – and not always successfully – with some jerky animations, mis-positioned elements and some performance issues. We didn&amp;#8217;t want to create a native app experience, but a simple mobile-optimised website with a responsive feel.&lt;/p&gt;

&lt;p&gt;I decided therefore to develop the site without the aid of an all-encompassing framework, but instead layer on richer functionality for more capable devices as and when it was appropriate. There are now a number of small, modular JavaScript libraries that aim to fill specific needs for mobile devices that can be cherry-picked as needed. Two such examples are &lt;a href='http://zeptojs.com/'&gt;Zepto.js&lt;/a&gt; and &lt;a href='http://xuijs.com/'&gt;XUI&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='a_website_is_a_website_is_a_website'&gt;A website is a website is a website&lt;/h3&gt;

&lt;p&gt;We were making a mobile optimised website, so we decided it should behave much like a website, and work within the confines of a mobile web browser. The back button should work, links should behave like links and most importantly, it should continue to provide a web experience for phones without touch interactions.&lt;/p&gt;

&lt;p&gt;At the same time, we wanted smartphones with fast JavaScript engines to enjoy a &amp;#8216;single-page&amp;#8217; experience with Ajax loading of content to improve perceived performance. This is a classic use-case for progressive enhancement. All the links in the website point to full URLs, and so work fine without JavaScript enabled. However, for smartphones, link activations are intercepted using JavaScript and the target content is loaded with Ajax and injected into the existing page. This means that only body content is loaded and re-drawn for each page, giving the site a more responsive app-like feel.&lt;/p&gt;

&lt;p&gt;However, the browser address bar is still updated as the user navigates around, allowing for favourites to be set, deep links to be emailed, tweeted and bookmarked. A simple but effective example of the importance of this was demonstrating during the festival by the use of deep links in tweets from the official Book Festival twitter account to link to specific day listings and events. Another feature that was explored but not implemented was the use of QR codes around the physical festival site to allow deep linking into specific event, author or book pages.&lt;/p&gt;

&lt;p&gt;The &amp;#8216;single-page&amp;#8217; style of navigation was achieved using a simple combination of the &lt;a href='http://zeptojs.com/'&gt;Zepto.js&lt;/a&gt; mobile-optimised JavaScript library and a &lt;a href='https://github.com/jimisaacs/zepto-pjax'&gt;modified version of Pjax&lt;/a&gt; - another small library that uses the HTML5 history API and Ajax to load and inject content. The back-end &lt;a href='http://rubyonrails.org/'&gt;Ruby on Rails&lt;/a&gt; application is modified to respond with only the page body content when a Pjax request is made, but with the full HTML document for all other requests.&lt;/p&gt;

&lt;h3 id='boilerplates'&gt;Boilerplates&lt;/h3&gt;

&lt;p&gt;Another tool that I found useful to kick start the development process was &lt;a href='http://html5boilerplate.com/mobile/'&gt;HTML5 Mobile Boilerplate&lt;/a&gt;. Based on the &lt;a href='http://html5boilerplate.com/'&gt;HTML5 Boilerplate&lt;/a&gt;, it provides HTML, CSS and JavaScript starting files with commonly used code and conventions specific to mobile-optimised sites. The golden rule is to critically evaluate everything that is provided, understand what it is for, decide whether it is necessary in the context of your own project and remove it if it is not relevant.&lt;/p&gt;

&lt;p&gt;For example, in the case of the Book Festival site, I eventually removed the reference to &lt;a href='http://www.modernizr.com/'&gt;Modernizr&lt;/a&gt;, which detects browser features and allows the developer to progressively enhance based on support for specific browser capabilities. I just wasn&amp;#8217;t using it for anything important, and so the bandwidth savings gained from removing it trumped any minor issues that it might have helped fix.&lt;/p&gt;

&lt;h2 id='open_source_ftw'&gt;Open source FTW&lt;/h2&gt;

&lt;p&gt;As part of the project, all &lt;a href='https://github.com/festivalslab/edbookfest-mobile'&gt;source code&lt;/a&gt; has been released under a GNU General Public License on Github. Feel free to fork it and play around. The Book Festival are planning on opening up listings data in the future, but access can currently be requested on a case-by-case basis. See the &lt;a href='https://github.com/festivalslab/edbookfest-mobile'&gt;README&lt;/a&gt; on Github for more information.&lt;/p&gt;

&lt;h2 id='thank_you'&gt;Thank you&lt;/h2&gt;

&lt;p&gt;This project would not have been possible without the support of the &lt;a href='http://festivalslab.com/'&gt;Edinburgh Festivals Innovation Lab&lt;/a&gt;, and in particular I would like to thank &lt;a href='http://rohangunatillake.com/'&gt;Rohan Gunatillake&lt;/a&gt; and &lt;a href='http://benwerd.com/'&gt;Ben Werdmuller&lt;/a&gt; for organising &lt;a href='http://culturehackscotland.com/'&gt;Culture Hack Scotland&lt;/a&gt; and providing excellent motivational impetus. One of the goals of the hack day was to foster co-operation and partnerships between the cultural sector and independent developers, and I&amp;#8217;m very glad to have been part of an example of that working successfully and producing something with a far wider output that just a fun hack.&lt;/p&gt;

&lt;p&gt;Secondly thanks to everyone at the Edinburgh International Book Festival, and in particular &lt;a href='https://twitter.com/ACoulton'&gt;Andrew Coulton&lt;/a&gt;, who despite being phenomenally busy in the run-up to the festival found time to provide detailed and helpful feedback and support.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Culture Hack Scotland 2011</title>
      <link href="http://tinnedfruit.com/2011/05/10/culture-hack-scotland-2011.html" />
      <updated>2011-05-10T00:00:00+01:00</updated>
      <id>http://tinnedfruit.com/2011/05/10/culture-hack-scotland-2011</id>
      <content type="html">&lt;p&gt;&lt;img alt='BookFest in action at Charlotte Square Gardens' src='http://images.tinnedfruit.com/blog/20110510/bookfest.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;Last weekend I attended &lt;a href='http://culturehackscotland.com/'&gt;Culture Hack Scotland&lt;/a&gt;, a fantastic hack day organised by the fine people at &lt;a href='http://festivalslab.com/'&gt;festivalslab&lt;/a&gt;. The &lt;a href='http://culturehackscotland.com/about/data'&gt;range of data&lt;/a&gt; available was impressive, and the &lt;a href='http://culturehackscotland.com/showcase'&gt;quality of the work&lt;/a&gt; produced by those attending was phenomenal. Congratulations to &lt;a href='http://twitter.com/rohan_21awake'&gt;Rohan Gunatillake&lt;/a&gt; and &lt;a href='https://twitter.com/benwerd'&gt;Ben Werdmuller&lt;/a&gt; for a superb event.&lt;/p&gt;

&lt;p&gt;For my own hack, I decided to focus on the &lt;a href='http://www.edbookfest.co.uk/'&gt;Edinburgh International Book Festival&lt;/a&gt;, which I thought might be neglected somewhat given the richness of the &lt;a href='http://www.edfringe.com/'&gt;Edinburgh Fringe&lt;/a&gt; data available, and the fact that it didn&amp;#8217;t have its own dedicated data sets. I wanted to produce a resource for people such as myself who seem to be afflicted by a gnawing insecurity of their own cultural viability. I greatly enjoy books, but I am by no means literary. I read plenty, but I don&amp;#8217;t take a great interest in the authors themselves. When attending a book event, the author becomes the centre of focus, and so I wanted to produce a tool that would help attendees discover more about the creators of the books that they have been enjoying.&lt;/p&gt;

&lt;p&gt;The result of this is &lt;a href='http://heroku.bookfest.com'&gt;BookFest&lt;/a&gt;, a mobile application for discovering more about the authors at The Edinburgh International Book Festival. The &lt;a href='http://github.com/froots/bookfest'&gt;code is available for mockery, forkery and hackery on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='data_sources'&gt;Data sources&lt;/h2&gt;

&lt;p&gt;The listings data for the Book Festival are taken from the &lt;a href='http://projects.festivalslab.com/2010/'&gt;2010 Festival Listings API&lt;/a&gt; created by Ben Werdmuller specifically for Culture Hack Scotland. festivalslab are planning on having a live API for the 2011 festivals which I am very much looking forward to.&lt;/p&gt;

&lt;p&gt;The listings API provides only event titles and descriptions and does not provide a specific field for authors, so the &lt;a href='http://code.google.com/apis/books/'&gt;Google Books Search API&lt;/a&gt; was used to get matching books based on the event title, and a list of unique authors of these books was collated. I then removed any authors that don&amp;#8217;t appear in the title. This works pretty well for finding the actual authors for an event.&lt;/p&gt;

&lt;p&gt;Once I had authors, I could then query the Google Books API again for a proper bibliography. I was hoping to be able to show Google Books previews inline in the app, but there simply are not that many available.&lt;/p&gt;

&lt;p&gt;The rest of the hack was spent adding value, and yes, gimmicks. I used the &lt;a href='http://www.guardian.co.uk/open-platform'&gt;Guardian Open Platform API&lt;/a&gt; to pull Guardian articles relating to or written by the author, added the inevitable &lt;a href='http://dev.twitter.com/'&gt;Twitter&lt;/a&gt; search, and grabbed photos of the author from the &lt;a href='http://code.google.com/apis/imagesearch/'&gt;Google Image Search API&lt;/a&gt;. The reason for the latter feature should be clear - few people really know what a particular author actually looks like. One weakness with this approach is that a &lt;a href='http://bookfest.heroku.com/#/images/David%20Mitchell'&gt;search for David Mitchell&lt;/a&gt; finds a lot of pictures of &lt;a href='http://en.wikipedia.org/wiki/David_Mitchell_(actor)'&gt;TV's David Mitchell&lt;/a&gt;, and very few of the &lt;a href='http://en.wikipedia.org/wiki/David_Mitchell_(author)'&gt;David Mitchell&lt;/a&gt; that wrote &lt;a href='http://bookfest.heroku.com/#/books/detail/9780375507250'&gt;Cloud Atlas&lt;/a&gt; and &lt;a href='http://bookfest.heroku.com/#/books/David%20Mitchell'&gt;other brain-melting fiction stonkers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My favourite feature of all is the &lt;a href='http://bookfest.heroku.com/#/sign/David%20Mitchell'&gt;signature facility&lt;/a&gt;. If you have forgotten to bring a book by the author and do not wish to buy another copy at the festival book store, you can simply ask them to scribble on your touch-enabled device. For this I used the demo of the &lt;a href='http://sidelab.github.com/interact/'&gt;Interact JavaScript library&lt;/a&gt; that consolidates mouse and touch events for different devices. Of course, this feature is ridiculous as there is really no way to get the signature where it should be - in a copy of the author&amp;#8217;s book. For that, we will have to settle for &lt;a href='http://en.wikipedia.org/wiki/LongPen'&gt;Margaret Atwood&amp;#8217;s LongPen device&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='technologies'&gt;Technologies&lt;/h2&gt;

&lt;p&gt;The app is hosted on &lt;a href='http://www.heroku.com'&gt;Heroku&lt;/a&gt;, and uses the &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra Ruby framework&lt;/a&gt; on the back-end. This uses the &lt;a href='http://rubygems.org/gems/rest-client'&gt;rest-client&lt;/a&gt; and &lt;a href='http://rubygems.org/gems/google-book'&gt;google-book&lt;/a&gt; gems for making API requests. On the front end I have used &lt;a href='http://jquerymobile.com/'&gt;jQuery Mobile&lt;/a&gt;, which provides a decent mobile-style UI framework and an Ajax page model to give the website a more native application feel. jQuery Mobile is still in alpha, and so some of the rendering and animation feels a little unfinished at the moment, but overall it&amp;#8217;s useful for getting something working very quickly.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href='http://bookfest.heroku.com'&gt;BookFest at http://bookfest.heroku.com&lt;/a&gt;&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Testing Backbone applications with Jasmine and Sinon – Part 3. Routers and Views</title>
      <link href="http://tinnedfruit.com/2011/04/26/testing-backbone-apps-with-jasmine-sinon-3.html" />
      <updated>2011-04-26T00:00:00+01:00</updated>
      <id>http://tinnedfruit.com/2011/04/26/testing-backbone-apps-with-jasmine-sinon-3</id>
      <content type="html">&lt;nav&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href='/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html'&gt;Part 1: Introduction&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;Part 2: Models and Collections&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;Part 3: Routers and Views&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;&lt;aside&gt;
  &lt;p&gt;&lt;strong&gt;Update 19th June 2012:&lt;/strong&gt; Minor changes for Backbone 0.9.3&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Update 13th September 2011:&lt;/strong&gt; This series has now been updated to reflect changes in Backbone 0.5.3.&lt;/p&gt;
&lt;/aside&gt;&lt;aside&gt;
  &lt;p&gt;This article series has been translated to &lt;a href='http://science.webhostinggeeks.com/testing-backbone-app'&gt;Serbo-Croatian&lt;/a&gt; by Anja Skrba from &lt;a href='http://webhostinggeeks.com/'&gt; Webhostinggeeks.com&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id='overview'&gt;Overview&lt;/h2&gt;

&lt;p&gt;This is the third and final part in a series of articles demonstrating how to test a &lt;a href='http://documentcloud.github.com/backbone/'&gt;Backbone.js&lt;/a&gt; application, employing the &lt;a href='http://pivotal.github.com/jasmine/'&gt;Jasmine BDD&lt;/a&gt; test framework and the &lt;a href='http://sinonjs.org/'&gt;Sinon.JS&lt;/a&gt; spying, stubbing and mocking library If you haven&amp;#8217;t yet read the &lt;a href='/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html'&gt;first&lt;/a&gt; or &lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;second&lt;/a&gt; parts, take a look now.&lt;/p&gt;

&lt;p&gt;In this final part, we&amp;#8217;ll be looking at some methods for unit testing Backbone routers and views. These object types both present their own unique challenges for testing, but &lt;em&gt;Jasmine BDD&lt;/em&gt; and &lt;em&gt;Sinon.JS&lt;/em&gt; provide the tools we need to isolate them and fake external code and system dependencies. We will be examining the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;different approaches to testing Backbone routes&lt;/li&gt;

&lt;li&gt;methods for testing view rendering&lt;/li&gt;

&lt;li&gt;using DOM fixtures in your specs&lt;/li&gt;

&lt;li&gt;using the &lt;em&gt;jasmine-jquery&lt;/em&gt; plugin&lt;/li&gt;

&lt;li&gt;testing view event handlers&lt;/li&gt;

&lt;li&gt;using fake timers to manipulate timed events&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='routers'&gt;Routers&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Backbone.js&lt;/em&gt; router objects are responsible for URL hash routing within your application, and can also be used for initialisation tasks if that&amp;#8217;s how you choose to structure your code.&lt;/p&gt;

&lt;p&gt;When a URL route is matched in your application, Backbone calls the router method associated with the route. It also triggers a route event in the form &lt;code&gt;route:[action]&lt;/code&gt; where &lt;code&gt;action&lt;/code&gt; is the name of your method.&lt;/p&gt;

&lt;p&gt;Whether you use a router method or set up event handlers to bind to the route event is up to you. I have had some success using event handlers for routes, as you can then delegate behaviour to the specific objects in the application that need to respond. Single route methods can become monolithic and difficult to test in large applications.&lt;/p&gt;

&lt;p&gt;For this example, however, we&amp;#8217;ll use simple route methods. Our approach will be to test two aspects of the router: firstly we&amp;#8217;ll test the route URLs themselves to make sure a particular URL will fire a particular route method; and secondly we&amp;#8217;ll look at directly testing router methods.&lt;/p&gt;

&lt;h3 id='example_1_testing_routes'&gt;Example 1: Testing routes&lt;/h3&gt;

&lt;p&gt;Our todo application will be driven by routes. When a user navigates to the home page for the first time, we want to display their to do list. In our code, the steps required are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The AppRouter responds to the home page route (represented by an empty hash)&lt;/li&gt;

&lt;li&gt;The &lt;code&gt;home&lt;/code&gt; route method instantiates a &lt;code&gt;TodoListView&lt;/code&gt; and a &lt;code&gt;Todos&lt;/code&gt; collection (created in &lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;part 2&lt;/a&gt; of this article).&lt;/li&gt;

&lt;li&gt;The &lt;code&gt;Todos&lt;/code&gt; collection is asked to fetch its contents from the server.&lt;/li&gt;

&lt;li&gt;When this response is received, the &lt;code&gt;TodoListView&lt;/code&gt; renders the list.&lt;/li&gt;

&lt;li&gt;The rendering of each individual &lt;code&gt;Todo&lt;/code&gt; item is delegated to new instances of a &lt;code&gt;TodoView&lt;/code&gt; object.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;#8217;s quite a lot of code to test. The router is responsible for the first three of these steps. Firstly we&amp;#8217;ll look at how to test whether a router responds correctly to a particular URL. This could potentially be tricky, as the &lt;em&gt;Backbone.js&lt;/em&gt; routing system responds to changes in the browser address field. It might be possible to directly manipulate the browser address, but Backbone 0.5 and above provides a &lt;code&gt;navigate&lt;/code&gt; method on router objects that can be used to simulate a URL change.&lt;/p&gt;

&lt;p&gt;Normally in an application you would instantiate a router once per page load, and run &lt;code&gt;Backbone.history.start()&lt;/code&gt; to start Backbone&amp;#8217;s route listening. However, Backbone will only allow you to run &lt;code&gt;Backbone.history.start()&lt;/code&gt; once for each page load. Running it a second time will result in an error being thrown.&lt;/p&gt;

&lt;p&gt;The simplest way around this is to wrap the call to &lt;code&gt;Backbone.history.start()&lt;/code&gt; in a try/catch block.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a spec:&lt;/p&gt;

&lt;h4 id='id21'&gt;&lt;code&gt;AppRoutes.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;AppRouter routes&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;history&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;start&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;silent&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;pushState&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;navigate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;elsewhere&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;fires the index route with a blank hash&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;route:index&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;navigate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledOnce&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The spec binds the &lt;code&gt;route:index&lt;/code&gt; event to an anonymous &lt;em&gt;Sinon.JS&lt;/em&gt; spy function, allowing us to track whether and how it was called. We then ensure that the URL fragment has the value we want to test, in this case, an empty value. Calling &lt;code&gt;Backbone.history.start()&lt;/code&gt; would normally trigger an initial &lt;em&gt;Backbone.js&lt;/em&gt; routing check. However, by passing an option hash that includes &lt;code&gt;silent: true&lt;/code&gt; we avoid the immediate route match. Note that we are also optionally using HTML5 &lt;em&gt;pushState&lt;/em&gt; for browsers that support it.&lt;/p&gt;

&lt;p&gt;The example itself triggers the route matching by calling the &lt;code&gt;navigate&lt;/code&gt; method on the router with the URL fragment as the first argument. If a truthy second argument is passed, Backbone will also call any matching route methods and trigger route events.&lt;/p&gt;

&lt;p&gt;To ensure that the route method and event is always fired, we navigate away somewhere else silently during the setup phase, just to ensure that the URL fragments are different.&lt;/p&gt;

&lt;p&gt;Once the routing check has been performed, we expect that our route spy has been called once, and that it has been called with no arguments, as there will be no parameters associated with the home route.&lt;/p&gt;

&lt;p&gt;When the example is run, we get an expected error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ReferenceError: AppRouter is not defined&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s fix this by creating our &lt;code&gt;AppRouter&lt;/code&gt;. Don&amp;#8217;t forget to include it in &lt;code&gt;jasmine.yml&lt;/code&gt; if necessary:&lt;/p&gt;

&lt;h4 id='id22'&gt;&lt;code&gt;AppRouter.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Running the specs again produces the following error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TypeError: Cannot call method &amp;#39;navigate&amp;#39; of undefined&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hmm, for some reason &lt;code&gt;Backbone.history&lt;/code&gt; is undefined, and so there is no &lt;code&gt;navigate&lt;/code&gt; method on it. It turns out that &lt;em&gt;Backbone.js&lt;/em&gt; creates an instance of &lt;code&gt;Backbone.History&lt;/code&gt; (upper case &amp;#8216;H&amp;#8217;) called &lt;code&gt;Backbone.history&lt;/code&gt; (lower case &amp;#8216;h&amp;#8217;) once a router has been created that has at least one route specified on it. This makes sense, as history management is only required if there are routes to respond to.&lt;/p&gt;

&lt;p&gt;We can now create our route:&lt;/p&gt;

&lt;h4 id='id23'&gt;&lt;code&gt;AppRouter.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;

  &lt;span class='nx'&gt;routes&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;index&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  
  &lt;span class='nx'&gt;index&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and our spec passes.&lt;/p&gt;

&lt;p&gt;Now that our index route is being tested successfully, lets try the todo detail route. At some point, we&amp;#8217;ll want to show the user details of a particular to do item. For example, some notes, tags and scheduling information might be displayed. The URL fragment for showing this detailed view would be &lt;code&gt;todo/1&lt;/code&gt; for a &lt;code&gt;Todo&lt;/code&gt; with an &lt;code&gt;id&lt;/code&gt; of 1. Let&amp;#8217;s write a spec to test that our router handles this successfully.&lt;/p&gt;

&lt;h4 id='id24'&gt;&lt;code&gt;AppRoutes.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;fires the todo detail route&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;route:todo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;navigate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;todo/1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledOnce&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;routeSpy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This spec is very similar to the one for the home route, but we are now binding a spy to the &lt;code&gt;route:todo&lt;/code&gt; event and testing that the &lt;code&gt;routeSpy&lt;/code&gt; is called with the &lt;code&gt;id&lt;/code&gt; parameter from the URL.&lt;/p&gt;

&lt;p&gt;This fails with the following messages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected Function to have been called once.
Expected Function to have been called with &amp;#39;1&amp;#39;.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is exactly what we were expecting. Now let&amp;#8217;s create the route:&lt;/p&gt;

&lt;h4 id='id25'&gt;&lt;code&gt;AppRouter.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;

  &lt;span class='nx'&gt;routes&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;todo/:id&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;todo&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  
  &lt;span class='nx'&gt;index&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{},&lt;/span&gt;
  &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And again, we&amp;#8217;re green. Simply by adding the route to the hash and creating an empty callback ensures that the &lt;code&gt;route:todo&lt;/code&gt; event is fired when the URL hash matches.&lt;/p&gt;

&lt;p&gt;We could enhance these specs by ensuring that only numerical values are valid for the &lt;code&gt;id&lt;/code&gt;, and we could also check that our route methods are actually called by wrapping them with a &lt;em&gt;Sinon.JS&lt;/em&gt; spy.&lt;/p&gt;

&lt;p&gt;Now that we have some routes, we need to test that our route methods are behaving as they should be.&lt;/p&gt;

&lt;h3 id='example_2_testing_router_methods'&gt;Example 2: Testing router methods&lt;/h3&gt;

&lt;p&gt;Once we have tested that the correct routes are actually being fired, we can test route methods simply by calling them. To test our &lt;code&gt;index&lt;/code&gt; method, we need to ensure that it instantiates a &lt;code&gt;TodoListView&lt;/code&gt; and a &lt;code&gt;Todos&lt;/code&gt; collection in the correct way. We&amp;#8217;ll need to create fake objects for both.&lt;/p&gt;

&lt;h4 id='id26'&gt;&lt;code&gt;AppRouter.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;AppRouter&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoListViewStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;TodoListView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;());&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todosCollectionStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Todos&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;afterEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;TodoListView&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;First we create our router instance for testing. We then create a bare &lt;em&gt;Backbone.js&lt;/em&gt; Collection object to act as the &lt;code&gt;Todos&lt;/code&gt; collection that will be returned when we stub out its constructor function. Finally, we create &lt;em&gt;Sinon.JS&lt;/em&gt; stubs for both the &lt;code&gt;TodoListView&lt;/code&gt; constructor and the &lt;code&gt;Todos&lt;/code&gt; collection constructor, returning a new &lt;em&gt;Backbone.js&lt;/em&gt; View and our bare collection respectively.&lt;/p&gt;

&lt;p&gt;Now to write the specs:&lt;/p&gt;

&lt;h4 id='id27'&gt;&lt;code&gt;AppRouter.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Index handler&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;when no Todo list exists&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      
    &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;index&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;creates a Todo list collection&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todosCollectionStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledOnce&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todosCollectionStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;  
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWithExactly&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;creates a Todo list view&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoListViewStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledOnce&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoListViewStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
          &lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt;
        &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Before each spec, we call our &lt;code&gt;index&lt;/code&gt; method for testing.&lt;/p&gt;

&lt;p&gt;In the first spec we check that the &lt;code&gt;Todos&lt;/code&gt; collection constructor has been called exactly once, and that it was called with no arguments.&lt;/p&gt;

&lt;p&gt;In the second spec, we check that the &lt;code&gt;TodoListView&lt;/code&gt; constructor was also called once, and that it was called with a hash object containing our stubbed collection instance. In this way we are testing that the application is linking the &lt;code&gt;TodoListView&lt;/code&gt; with its data source, the &lt;code&gt;Todos&lt;/code&gt; collection.&lt;/p&gt;

&lt;p&gt;When these specs run, we get four failures:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;creates a Todo list collection
  Expected Function to have been called once.
  Expected Function to have been called with exactly.

creates a Todo list view
  Expected Function to have been called once
  Expected Function to have been called with ... &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, let&amp;#8217;s write the code to make these pass:&lt;/p&gt;

&lt;h4 id='id28'&gt;&lt;code&gt;AppRouter.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  
  &lt;span class='p'&gt;...&lt;/span&gt;
  
  &lt;span class='nx'&gt;index&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todosView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Simple. We now need to test that collection&amp;#8217;s data is fetched when the &lt;code&gt;index&lt;/code&gt; route is run. This is done by simply calling the &lt;code&gt;Todos&lt;/code&gt; collection&amp;#8217;s &lt;code&gt;fetch&lt;/code&gt; method. Let&amp;#8217;s write another spec.&lt;/p&gt;

&lt;p&gt;First, we need to stub the collection&amp;#8217;s &lt;code&gt;fetch&lt;/code&gt; method so that it performs no action, but allows us to spy on it. We add the following line to our &lt;code&gt;beforeEach&lt;/code&gt; method just after creating &lt;code&gt;this.collection&lt;/code&gt;:&lt;/p&gt;

&lt;h4 id='id29'&gt;&lt;code&gt;AppRouter.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;AppRouter&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='p'&gt;...&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetchStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;fetch&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='p'&gt;...&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We can then add our new spec after the previous two:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;fetches the Todo list from the server&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetchStub&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledOnce&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetchStub&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This fails as expected:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fetches the Todo list from the server
  Expected Function to have been called once.
  Expected Function to have been called with.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And making the spec pass is simple:&lt;/p&gt;

&lt;h4 id='id30'&gt;&lt;code&gt;AppRouter.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;AppRouter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Router&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  
  &lt;span class='p'&gt;...&lt;/span&gt;
  
  &lt;span class='nx'&gt;index&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todosView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetch&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Our examples so far have been simple. You can see that routers can easily create a lot of other objects, and then call methods on those objects in order to get things rolling in your application.&lt;/p&gt;

&lt;p&gt;If you are instantiating your initial application objects like this in your routers, then you&amp;#8217;ll be creating a lot of stubs and mocks in your router specs. This is a matter of application design. For simple applications it is probably not a big issue, but this approach soon gets unwieldy.&lt;/p&gt;

&lt;p&gt;An alternative approach is to instantiate any initial &lt;em&gt;Backbone.js&lt;/em&gt; objects in an overall application initialisation method that is run when the page is first loaded, for example in a DOM ready handler. The router would also be instantiated and &lt;em&gt;Backbone.js&lt;/em&gt;&amp;#8217;s history object initialised at this point. The primary application objects that you have created (usually the views) can then bind and unbind to the built-in &lt;em&gt;Backbone.js&lt;/em&gt; route events as required within their own code. In this way you are effectively delegating responsibility to the individual application objects so they are in charge of their own destiny. The outcome of this is code that is easier to test, and easier to maintain. If your specs become unwieldy, long and difficult to set up, then this is often a code smell suggesting that you should probably simplify or refactor your code.&lt;/p&gt;

&lt;p&gt;Looking back to the top of example 1, we can see that we have now tested the first three steps required to render our to do list. The last two steps are the responsibility of two views: the &lt;code&gt;TodoListView&lt;/code&gt; and the &lt;code&gt;TodoView&lt;/code&gt;. Let&amp;#8217;s take a look at testing views, then.&lt;/p&gt;

&lt;h2 id='views'&gt;Views&lt;/h2&gt;

&lt;p&gt;Because our app uses jQuery for DOM manipulation, it makes some sense to use jQuery to test the rendered elements that our views will produce. Fortunately there is a &lt;a href='https://github.com/velesin/jasmine-jquery'&gt;Jasmine BDD jQuery plugin&lt;/a&gt; specifically for this purpose. The plugin provides two key features: firstly there are a number of &lt;em&gt;Jasmine&lt;/em&gt; matchers to test jQuery wrapped sets and elements and secondly, it provides the ability to create temporary HTML fixtures for your specs to use.&lt;/p&gt;

&lt;p&gt;To use the plugin, just include the &lt;code&gt;jasmine-jquery.js&lt;/code&gt; file in your &lt;code&gt;jasmine.yml&lt;/code&gt; or &lt;code&gt;SpecRunner.html&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id='example_1_creating_the_root_element'&gt;Example 1: Creating the root element&lt;/h3&gt;

&lt;p&gt;In our first view example, we&amp;#8217;ll create a simple spec to check that our &lt;code&gt;TodoListView&lt;/code&gt; has created the expected element when it is initialised. &lt;em&gt;Backbone.js&lt;/em&gt; views will create an empty DOM element as soon as they are initialised, but this element will not be attached to the visible DOM. This allows a view to be constructed without unduly affecting rendering performance.&lt;/p&gt;

&lt;p&gt;Our spec is pretty simple:&lt;/p&gt;

&lt;h4 id='id31'&gt;&lt;code&gt;TodoListView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;TodoListView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Instantiation&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should create a list element&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;nodeName&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;UL&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Running this spec produces the following failure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected &amp;#39;DIV&amp;#39; to equal &amp;#39;UL&amp;#39;.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can fix this easily in our &lt;code&gt;TodoListView.js&lt;/code&gt; by specifying the built-in &lt;em&gt;Backbone.js&lt;/em&gt; &lt;code&gt;tagName&lt;/code&gt; property for the view:&lt;/p&gt;

&lt;h4 id='id32'&gt;&lt;code&gt;TodoListView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;tagName&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s also check that the element has the right class:&lt;/p&gt;

&lt;h4 id='id33'&gt;&lt;code&gt;TodoListView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should have a class of &amp;#39;todos&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toHaveClass&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This uses the &lt;code&gt;toHaveClass&lt;/code&gt; matcher created by the &lt;em&gt;jasmine-jquery&lt;/em&gt; plugin which operates on jQuery objects. If we had not used the plugin, the expectation would have looked something like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;hasClass&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toBeTruthy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which would produce a failure output like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected false to be truthy.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is not very helpful for debugging purposes. Using the &lt;em&gt;jasmine-jquery&lt;/em&gt; matcher produces this failure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected &amp;#39;&amp;lt;ul&amp;gt;&amp;lt;/ul&amp;gt;&amp;#39; to have class &amp;#39;todos&amp;#39;.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, we can easily fix this with a simple &lt;code&gt;className&lt;/code&gt; property on the view object.&lt;/p&gt;

&lt;h4 id='id34'&gt;&lt;code&gt;TodoListView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;tagName&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='nx'&gt;className&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;todos&amp;quot;&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s move on to testing the actual rendering of our to do list content.&lt;/p&gt;

&lt;h3 id='example_2_rendering'&gt;Example 2: Rendering&lt;/h3&gt;

&lt;p&gt;When we ask our to do list to render, it will create a task entry for each instance of a &lt;code&gt;Todo&lt;/code&gt; model in the &lt;code&gt;Todos&lt;/code&gt; collection. Each one of these tasks is a view instance with a reference to the model that will be rendered.&lt;/p&gt;

&lt;p&gt;So, when the &lt;code&gt;TodoListView&lt;/code&gt;&amp;#8217;s &lt;code&gt;render()&lt;/code&gt; method is called, we want to test that a &lt;code&gt;TodoView&lt;/code&gt; is instantiated for each model in the associated collection.&lt;/p&gt;

&lt;p&gt;Once again, because we are not currently testing the &lt;code&gt;TodoView&lt;/code&gt; object, we will stub it with a basic &lt;em&gt;Backbone.js&lt;/em&gt; view. As discussed in &lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;part 2&lt;/a&gt; of this series, I find that this is by far the easiest way to isolate a &lt;em&gt;Backbone.js&lt;/em&gt; object from other &lt;em&gt;Backbone.js&lt;/em&gt; objects in your specs without resorting to mocking and stubbing the whole &lt;em&gt;Backbone.js&lt;/em&gt; interface.&lt;/p&gt;

&lt;p&gt;We create a basic &lt;em&gt;Backbone.js&lt;/em&gt; view to stand in for the &lt;code&gt;TodoView&lt;/code&gt;, and then stub the &lt;code&gt;TodoView&lt;/code&gt; constructor function, returning our basic &lt;em&gt;Backbone.js&lt;/em&gt; view instead of a real &lt;code&gt;TodoView&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;We then create a simple &lt;em&gt;Backbone.js&lt;/em&gt; collection with three models, and associate the &lt;code&gt;TodoList&lt;/code&gt; view instance with this collection. When the view&amp;#8217;s &lt;code&gt;render()&lt;/code&gt; method is called, the expected behaviour is then to call the &lt;code&gt;TodoView&lt;/code&gt; constructor once for each model in the collection.&lt;/p&gt;

&lt;h4 id='id35'&gt;&lt;code&gt;TodoListView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;TodoListView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='p'&gt;...&lt;/span&gt;

  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Rendering&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
    &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoViewStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;TodoView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo1&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo2&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo3&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo3&lt;/span&gt;
      &lt;span class='p'&gt;]);&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
    &lt;span class='nx'&gt;afterEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;TodoView&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should create a Todo view for each todo item&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoViewStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledThrice&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoViewStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo1&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoViewStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo2&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoViewStub&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo3&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Running this spec results in 3 errors:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TypeError: Attempted to wrap undefined property TodoView as function
TypeError: Cannot read property &amp;#39;calledThrice&amp;#39; of undefined
TypeError: Cannot call method &amp;#39;restore&amp;#39; of undefined&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is telling us that we need to create a &lt;code&gt;TodoView&lt;/code&gt; object.&lt;/p&gt;

&lt;h4 id='id36'&gt;&lt;code&gt;TodoView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, when we re-run the specs, we get this failure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected Function to have been called thrice.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and three of these:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected Function to have been called with {..}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Those are the proper failures. Let&amp;#8217;s fix it by writing the code we need.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;TodoListView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;

  &lt;span class='p'&gt;...&lt;/span&gt;

  &lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;each&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addTodo&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  
  &lt;span class='nx'&gt;addTodo&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;view&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Great. This passes, and we are now creating three &lt;code&gt;TodoViews&lt;/code&gt;. However, nothing will be rendered in the page. We need to make sure each &lt;code&gt;TodoView&lt;/code&gt;&amp;#8217;s &lt;code&gt;render()&lt;/code&gt; method is called.&lt;/p&gt;

&lt;p&gt;Firstly, we need to spy on the fake &lt;code&gt;TodoView&lt;/code&gt;&amp;#8217;s &lt;code&gt;render()&lt;/code&gt; method. We set this up in our &lt;code&gt;beforeEach&lt;/code&gt; function:&lt;/p&gt;

&lt;h4 id='id37'&gt;&lt;code&gt;TodoListView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoRenderSpy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;render&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and then the spec itself:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should render each Todo view&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledThrice&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The failure that results from running this spec can be fixed with the following one line change added to the &lt;code&gt;render()&lt;/code&gt; method in &lt;code&gt;TodosView.js&lt;/code&gt;:&lt;/p&gt;

&lt;h4 id='id38'&gt;&lt;code&gt;TodoView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;todoEl&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;However, we still need to append the rendered todo to our list. This is done with jQuery. We can either stub the jQuery &lt;code&gt;append&lt;/code&gt; method, or we can physically check that an element has been appended. To write a spec for this we first need to create a simple stubbed &lt;code&gt;render&lt;/code&gt; method on the &lt;code&gt;TodoView&lt;/code&gt; stub object that creates a DOM element and returns itself, like so:&lt;/p&gt;

&lt;h4 id='id39'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;createElement&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;li&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoRenderSpy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;render&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoViewStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;TodoView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoView&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and we can now write a spec to check that one of these elements has been appended for each model:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;appends the todo to the todo list&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;children&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This produces the following failure as expected:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected 0 to equal 3.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Lets&amp;#8217; fix that in &lt;code&gt;TodosView.js&lt;/code&gt;:&lt;/p&gt;

&lt;h4 id='id40'&gt;&lt;code&gt;TodosView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;addTodo&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;view&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;todoEl&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;todoEl&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Running the specs produces the same failure as before. What happened? This is a common gotcha when first starting out with &lt;em&gt;Backbone.js&lt;/em&gt;. Because the &lt;code&gt;addTodo()&lt;/code&gt; method is called as a callback from within an underscore.js &lt;code&gt;each()&lt;/code&gt; iterator, the scope for &lt;code&gt;addTodo&lt;/code&gt; is not the &lt;code&gt;TodoListView&lt;/code&gt; instance, but the &lt;code&gt;todo&lt;/code&gt; model instance that is the target of the iteration cycle. Because of this, there is no &lt;code&gt;el&lt;/code&gt; property on &lt;code&gt;this&lt;/code&gt;, and the append fails.&lt;/p&gt;

&lt;p&gt;Fortunately &lt;em&gt;underscore.js&lt;/em&gt; provides a convenience function to fix the scope for a method named &lt;code&gt;bindAll()&lt;/code&gt;. In a &lt;em&gt;Backbone.js&lt;/em&gt; application it is best called within the &lt;code&gt;initialize()&lt;/code&gt; method. It takes the intended scope as the first argument, and one or more methods on the current scope that are to have their scope set:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;initialize&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;_&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bindAll&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;addTodo&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This sets the scope for the &lt;code&gt;addTodo()&lt;/code&gt; method to be the &lt;code&gt;TodosView&lt;/code&gt; instance rather than the scope it was actually called with.&lt;/p&gt;

&lt;p&gt;Now the jQuery append is being called on the correct object, and the spec passes.&lt;/p&gt;

&lt;h3 id='example_3_rendering_html'&gt;Example 3: Rendering HTML&lt;/h3&gt;

&lt;p&gt;So far our views have not actually rendered anything. Our &lt;code&gt;TodoListView&lt;/code&gt; simply delegates the actual rendering of markup to the individual &lt;code&gt;TodoView&lt;/code&gt; objects below it. Let&amp;#8217;s test that these &lt;code&gt;TodoView&lt;/code&gt; elements are rendered as expected.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll start by just using some string manipulation to create HTML markup to be rendered using jQuery&amp;#8217;s &lt;code&gt;html()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;We will create two specs initially. The first will check that the view&amp;#8217;s &lt;code&gt;render()&lt;/code&gt; method returns the view instance. This is necessary for chaining, and something that we have already expected in the specs for &lt;code&gt;TodoListView&lt;/code&gt;. The second spec will check that the produced HTML is exactly as expected based on the properties of the model instance that is associated with our &lt;code&gt;TodoView&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;beforeEach&lt;/code&gt; function for these specs simply creates a sample model, and then instantiates a &lt;code&gt;TodoView&lt;/code&gt; and associates it with the model.&lt;/p&gt;

&lt;h4 id='id41'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;TodoView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;My Todo&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nx'&gt;priority&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nx'&gt;done&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Rendering&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;returns the view object&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;produces the correct HTML&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;innerHTML&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#todo/1&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;My Todo&amp;lt;/h2&amp;gt;&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When these specs are run, only the second one fails. The first spec that tests that the &lt;code&gt;TodoView&lt;/code&gt; instance is returned from &lt;code&gt;render()&lt;/code&gt; passes because &lt;em&gt;Backbone.js&lt;/em&gt; does this by default, and we haven&amp;#8217;t overwritten the &lt;code&gt;render&lt;/code&gt; method with our own version yet.&lt;/p&gt;

&lt;p&gt;The second spec fails with the following message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected &amp;#39;&amp;#39; to equal &amp;#39;&amp;lt;a href=&amp;quot;#todo/1&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;My Todo&amp;lt;/h2&amp;gt;&amp;lt;/a&amp;gt;&amp;#39;.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By default, the &lt;code&gt;render()&lt;/code&gt; method creates no markup. Let&amp;#8217;s write a simple replacement for &lt;code&gt;render()&lt;/code&gt;:&lt;/p&gt;

&lt;h4 id='id42'&gt;&lt;code&gt;TodoView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;template&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#todo/{{id}}&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;{{title}}&amp;lt;/h2&amp;gt;&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;output&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;template&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;{{id}}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;{{title}}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;html&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;output&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This simply specifies a string template and replaces some fields marked with double curly braces with their respective values from the associated model. Because we are returning the &lt;code&gt;TodoView&lt;/code&gt; instance from the method, the first spec also passes.&lt;/p&gt;

&lt;p&gt;It hardly needs saying that using an HTML string to test against like this is fraught with problems. It is extremely brittle. If you were to change one tiny thing about your template, including white space, your spec would fail, even thought the rendered output would be the same. It will also become time consuming to maintain as your template becomes more complex.&lt;/p&gt;

&lt;p&gt;It is far better to test your rendered output using jQuery to select and inspect attribute and text values, element counts and so on.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s write specs that check some key aspects of the expected output. Again, we are using the custom matchers added by the &lt;em&gt;jasmine-jquery&lt;/em&gt; plugin:&lt;/p&gt;

&lt;h4 id='id43'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Template&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;has the correct URL&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveAttr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;#todo/1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;has the correct title text&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveText&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;My Todo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now is a good time to take a look at fixture elements. So far, we have been setting jQuery expectations against the view&amp;#8217;s &lt;code&gt;el&lt;/code&gt; property. This is absolutely fine in many circumstances, and may actually be preferable a lot of the time. However, at times you will need to actually render some markup into the document. The best way to handle this within your specs is to use fixtures, a feature provided by the &lt;em&gt;jasmine-jquery&lt;/em&gt; plugin. Let&amp;#8217;s re-write that last spec to use fixtures:&lt;/p&gt;

&lt;h4 id='id44'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;TodoView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
 	&lt;span class='p'&gt;...&lt;/span&gt;
    &lt;span class='nx'&gt;setFixtures&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;ul class=&amp;quot;todos&amp;quot;&amp;gt;&amp;lt;/ul&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='p'&gt;...&lt;/span&gt;
  
  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Template&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      
    &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
      
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;has the correct URL&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveAttr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;#todo/1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;

    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;has the correct title text&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveText&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;My Todo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
      
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We are now appending the rendered todo item into the fixture, and setting expectations against the fixture rather than the view&amp;#8217;s &lt;code&gt;el&lt;/code&gt; property. One reason you might need to do this is when a &lt;em&gt;Backbone.js&lt;/em&gt; view is set up against a pre-existing DOM element. You would need to provide the fixture and test that the &lt;code&gt;el&lt;/code&gt; property is picking up the correct element when the view is instantiated.&lt;/p&gt;

&lt;h3 id='example_4_rendering_with_a_template_library'&gt;Example 4: Rendering with a template library&lt;/h3&gt;

&lt;p&gt;We can now start to make the template a little more complex by including some conditional logic. When a todo item is marked as done, we want to provide some visual feedback to the user in the form of a different background colour, or perhaps by striking through the title. We&amp;#8217;ll do this by attaching a class to the anchor.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s write a spec to test that this happens.&lt;/p&gt;

&lt;h4 id='id45'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;When todo is done&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;set&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;done&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;silent&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;has a done class&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.todos a:first-child&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toHaveClass&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;done&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This fails, as expected, with the following message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected &amp;#39;&amp;lt;a href=&amp;quot;#todo/1&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;My Todo&amp;lt;/h2&amp;gt;&amp;lt;/a&amp;gt;&amp;#39; 
to have class &amp;#39;done&amp;#39;.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We could fix this in our existing render method like so:&lt;/p&gt;

&lt;h4 id='id46'&gt;&lt;code&gt;TodoView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;template&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#todo/{{id}}&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;&amp;lt;h2&amp;gt;{{title}}&amp;lt;/h2&amp;gt;&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;output&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;template&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;{{id}}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;{{title}}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;html&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;output&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;done&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;addClass&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;done&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;However, you can see that this will get cumbersome quickly. The more logic we have here, the more complexity we introduce. This is where a template library can come in handy. There are many available, and exploring the options is beyond the scope of this article. For this example we&amp;#8217;ll use &lt;a href='https://github.com/wycats/handlebars.js'&gt;Handlebars.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll need to add &lt;code&gt;handlebars.js&lt;/code&gt; to &lt;code&gt;jasmine.yml&lt;/code&gt; or &lt;code&gt;SpecRunner.html&lt;/code&gt;. We should be able to rewrite our render code and get the existing specs passing without changing very much.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s our new &lt;code&gt;TodoView&lt;/code&gt; object, modified to use &lt;code&gt;handlebars.js&lt;/code&gt;:&lt;/p&gt;

&lt;h4 id='id47'&gt;&lt;code&gt;TodoView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  
  &lt;span class='nx'&gt;tagName&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;li&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  
  &lt;span class='nx'&gt;initialize&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;template&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Handlebars&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;compile&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;template&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  
  &lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;html&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;template&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toJSON&lt;/span&gt;&lt;span class='p'&gt;()));&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;initialize&lt;/code&gt; method compiles a Handlebars template provided as a string in the instantiation. Another way to reference a template would be by placing it in the page HTML and obtaining it via its &lt;code&gt;id&lt;/code&gt; attribute, which is a common approach with Handlebars. In a real application, it would be preferable to use the latter approach, and have your specs load the real template in for testing. One way to do this if your project uses Ruby is to use the &lt;a href='https://github.com/jnicklas/evergreen'&gt;Evergreen gem&lt;/a&gt; to handle template loading for you.&lt;/p&gt;

&lt;p&gt;For our purposes, we&amp;#8217;ll continue to use the string injection approach. We add a new directory named templates to the &lt;code&gt;spec&lt;/code&gt; directory, and add a new file named &lt;code&gt;todo-template.js&lt;/code&gt; which looks like this:&lt;/p&gt;

&lt;h4 id='id48'&gt;&lt;code&gt;todo-template.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;_&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='p'&gt;{},&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#todo/{{id}}&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s1'&gt;&amp;#39;&amp;lt;h2&amp;gt;{{title}}&amp;lt;/h2&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This simply creates or extends a templates object in the &lt;em&gt;Jasmine&lt;/em&gt; scope for each test and adds a &lt;code&gt;todo&lt;/code&gt; property containing the Handlebars template we want to use.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll need to add the templates folder reference to &lt;code&gt;jasmine.yml&lt;/code&gt; or &lt;code&gt;SpecRunner.html&lt;/code&gt;, and also update our existing specs slighly to provide the template when instantiating the &lt;code&gt;TodoView&lt;/code&gt; object:&lt;/p&gt;

&lt;h4 id='id49'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;TodoView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='p'&gt;...&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nx'&gt;template&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='p'&gt;...&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;All of the existing specs continue to pass with our new templating system in place, so we can now enhance the template with some logic for the done status:&lt;/p&gt;

&lt;h4 id='id50'&gt;&lt;code&gt;todo-template.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;_&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='p'&gt;{},&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#todo/{{id}}&amp;quot;{{#if done}} class=&amp;quot;done&amp;quot;{{/if}}&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s1'&gt;&amp;#39;&amp;lt;h2&amp;gt;{{title}}&amp;lt;/h2&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And that spec now passes as well.&lt;/p&gt;

&lt;h3 id='example_4_events'&gt;Example 4: Events&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Backbone.js&lt;/em&gt; views also allow the declaration of DOM events to be listened for and executed upon. The API to do this is simple: a hash of key/value pairs where the key is a string containing the event to be bound to and the selector to be used, and the value is the name of the method to use as the callback when the event is triggered.&lt;/p&gt;

&lt;p&gt;For our Todo app, we will provide a small edit icon for each to do item, which when clicked will replace the title text with an editable input field. Let&amp;#8217;s write a spec that checks for this behaviour:&lt;/p&gt;

&lt;h4 id='id51'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;TodoView&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='p'&gt;...&lt;/span&gt;
  
  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Edit state&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
    &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;When edit button handler fired&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      
      &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul.todos li:first&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;trigger&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
      
      &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;shows the edit input field&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;input.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
          &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toBeVisible&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
        &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
          &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;not&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toBeVisible&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
      
    &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This spec runs and fails with the following messages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected &amp;#39;&amp;#39; to be visible.
Expected &amp;#39;&amp;lt;h2&amp;gt;My Todo&amp;lt;/h2&amp;gt;&amp;#39; not to be visible.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To fix this, we first need to create the edit link and input field in our template:&lt;/p&gt;

&lt;h4 id='id52'&gt;&lt;code&gt;todo-template.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;_&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;templates&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='p'&gt;{},&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#todo/{{id}}&amp;quot;{{#if done}} class=&amp;quot;done&amp;quot;{{/if}}&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s1'&gt;&amp;#39;&amp;lt;h2&amp;gt;{{title}}&amp;lt;/h2&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s1'&gt;&amp;#39;&amp;lt;input class=&amp;quot;edit&amp;quot; type=&amp;quot;text&amp;quot; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s1'&gt;&amp;#39;value=&amp;quot;{{title}}&amp;quot; style=&amp;quot;display:none&amp;quot;/&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; 
          &lt;span class='s1'&gt;&amp;#39;&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;edit&amp;quot;&amp;gt;Edit&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then we add the events hash with our click event linked to an event handler:&lt;/p&gt;

&lt;h4 id='id53'&gt;&lt;code&gt;TodoView.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;TodoView&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;

  &lt;span class='p'&gt;...&lt;/span&gt;
  
  &lt;span class='nx'&gt;initialize&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;_&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bindAll&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;edit&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;template&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Handlebars&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;compile&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;template&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  
  &lt;span class='nx'&gt;events&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;click a.edit&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;edit&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;

  &lt;span class='nx'&gt;edit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;hide&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;input.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;show&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Don&amp;#8217;t forget to add a &lt;code&gt;_.bindAll&lt;/code&gt; call to set the scope of the edit callback. Our specs are all green again, and we can move on.&lt;/p&gt;

&lt;h3 id='example_5_animations_and_timing'&gt;Example 5: Animations and timing&lt;/h3&gt;

&lt;p&gt;Suppose that one of your esteemed designer colleagues deems that when the user clicks the edit icon, the title text should fade out and the input field should fade in over the course of half a second. Of course, you would think that this is unnecessary fluff in the user interface, but you are overruled and you must carry out the instruction to the full or be dismissed immediately.&lt;/p&gt;

&lt;p&gt;When it comes to actually carrying out the designer&amp;#8217;s instructions, the code could not be easier. We simply amend the edit method to use jQuery&amp;#8217;s &lt;code&gt;fadeIn&lt;/code&gt; and &lt;code&gt;fadeOut&lt;/code&gt; methods:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;edit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;fadeOut&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;500&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;fadeIn&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;500&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Great! All is well until you run the specs and are greeted with the following failure message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected &amp;#39;&amp;lt;h2 style=&amp;quot;opacity: 1; &amp;quot;&amp;gt;My Todo&amp;lt;/h2&amp;gt;&amp;#39; 
not to be visible.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The spec is checking the visible state of the title heading immediately after the &lt;code&gt;render()&lt;/code&gt; method is called. We need to wait for half a second before we check the state to give the animation time to complete.&lt;/p&gt;

&lt;p&gt;One way around this is to use &lt;em&gt;Jasmine&lt;/em&gt;&amp;#8217;s built-in support for asynchronous specs. The existing spec could be re-written like this:&lt;/p&gt;

&lt;h4 id='id54'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;When edit button handler fired&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul.todos li:first&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;trigger&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;shows the edit input field&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;waits&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;510&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;runs&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;input.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toBeVisible&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;not&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toBeVisible&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;          
    &lt;span class='p'&gt;})&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;With this approach, we&amp;#8217;re waiting for 510 milliseconds between the click event and the expectations, which are wrapped in a &lt;code&gt;runs()&lt;/code&gt; call to make them run after the wait has completed.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s not so bad, and the spec passes now. However, write more than a few of these asynchronous timed specs and you&amp;#8217;ll end up with a very slow-running spec suite. Our spec suite has gone from 0.15 seconds to 0.65 seconds just because of one spec.&lt;/p&gt;

&lt;p&gt;To eliminate this delay we can use the fake timing abilities of &lt;em&gt;Sinon.JS&lt;/em&gt;. Instead of actually waiting for half a second to pass, &lt;em&gt;Sinon.JS&lt;/em&gt; allows us to fake the passing of time itself. Unfortunately it doesn&amp;#8217;t actually manipulate the space/time continuum, which would have been very neat programming indeed, but simply mucks about with JavaScript&amp;#8217;s native time-keeping methods such as &lt;code&gt;setTimeout&lt;/code&gt; and &lt;code&gt;setInterval&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can re-write our spec to use &lt;em&gt;Sinon.JS&lt;/em&gt;&amp;#8217;s fake timers as follows:&lt;/p&gt;

&lt;h4 id='id55'&gt;&lt;code&gt;TodoView.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;When edit button handler fired&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;clock&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;useFakeTimers&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul.todos&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;view&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;render&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;el&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul.todos li:first&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;trigger&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;afterEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;clock&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;shows the edit input field&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;clock&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;tick&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;600&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;input.edit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toBeVisible&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;li&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;h2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;not&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toBeVisible&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Fake timers are initialised by calling &lt;code&gt;sinon.useFakeTimers()&lt;/code&gt; in the &lt;code&gt;beforeEach&lt;/code&gt; method. We must restore the native timer functions to their original state after our specs, so we create an &lt;code&gt;afterEach&lt;/code&gt; function which does this. Finally, the spec itself is responsible for moving the clock forward by a specified number of milliseconds before we run our expectations.&lt;/p&gt;

&lt;p&gt;Now when our specs pass, they pass in around 0.15 seconds again. Even though our application is now using animations, it has had minimal effect on our specs. This is most definitely a Good Thing, as it gives designers and developers the flexibility to tweak interface characteristics such as animations without being unduly held back by the test suite.&lt;/p&gt;

&lt;p&gt;The use of fake timers is not limited to animations, of course. They can be used wherever timing is important in your application. For example, you may have a regular polling request that updates some information every minute. Instead of letting a spec run for a full minute, or artificially changing the polling interval in your spec, you can forward the timer by a minute and test that another request has been made to the server.&lt;/p&gt;

&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;Testing user interface behaviours and interactions can sometimes be daunting, and test suites quite often end up being slow-running or incomplete because of the unique challenges the UI of web applications present. Although some of the techniques here are specific to &lt;em&gt;Backbone.js&lt;/em&gt;, many apply to jQuery and other rich web application interfaces in general.&lt;/p&gt;

&lt;p&gt;Throughout this series of articles, we have concentrated on writing unit tests where individual JavaScript objects are tested in isolation. Your test suite should also include some integration tests where objects are tested in combination with each other, and functional tests where an actual running application is tested using an automated browser driver such as Selenium or Web Driver. There are a pretty large number of frameworks, libraries and drivers that satisfy this need, but they can be difficult to set up, bug-prone and a challenge to debug. For this reason, the unit test suite is essential to catch as many problems as possible as early as possible, and to write test cases when bugs are discovered.&lt;/p&gt;

&lt;p&gt;I hope that this series of articles has given you some useful techniques to start testing your &lt;em&gt;Backbone.js&lt;/em&gt; applications, and not to be daunted by the apparent complexity that that may present at first. Like any seemingly complex task, testing is simply a matter of breaking the task down into smaller, more manageable units, and using a toolset to make this process faster and more efficient. Happy testing!&lt;/p&gt;
&lt;nav&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href='/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html'&gt;Part 1: Introduction&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;Part 2: Models and Collections&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;Part 3: Routers and Views&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;</content>
    </entry>
  
    <entry>
      <title>Testing Backbone applications with Jasmine and Sinon – Part 2. Models and Collections</title>
      <link href="http://tinnedfruit.com/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html" />
      <updated>2011-03-25T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2</id>
      <content type="html">&lt;nav&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href='/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html'&gt;Part 1: Introduction&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;Part 2: Models and Collections&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/04/26/testing-backbone-apps-with-jasmine-sinon-3.html'&gt;Part 3: Routers and Views&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;&lt;aside&gt;
  &lt;p&gt;&lt;strong&gt;Update 19th June 2012:&lt;/strong&gt; Minor changes for Backbone 0.9.3&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Update 13th September 2011:&lt;/strong&gt; This series has now been updated to reflect changes in Backbone 0.5.3.&lt;/p&gt;
&lt;/aside&gt;&lt;aside&gt;
  &lt;p&gt;This article series has been translated to &lt;a href='http://science.webhostinggeeks.com/testing-backbone-app'&gt;Serbo-Croatian&lt;/a&gt; by Anja Skrba from &lt;a href='http://webhostinggeeks.com/'&gt; Webhostinggeeks.com&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id='overview'&gt;Overview&lt;/h2&gt;

&lt;p&gt;This is the second in a series of articles demonstrating how to test a &lt;a href='http://documentcloud.github.com/backbone/'&gt;Backbone.js&lt;/a&gt; application, employing the &lt;a href='http://pivotal.github.com/jasmine/'&gt;Jasmine BDD&lt;/a&gt; test framework and the &lt;a href='http://sinonjs.org/'&gt;Sinon.JS&lt;/a&gt; spying, stubbing and mocking library. If you haven&amp;#8217;t yet read the &lt;a href='/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html'&gt;first part&lt;/a&gt;, take a look now.&lt;/p&gt;

&lt;p&gt;In this part, we&amp;#8217;ll look at some examples for testing Backbone models and collections. Along the way, we&amp;#8217;ll be introducing techniques that help to keep your Jasmine specs fast, clean and effective, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how to isolate each of your Backbone objects for testing&lt;/li&gt;

&lt;li&gt;using Sinon&amp;#8217;s fake server feature to mock server responses to Ajax requests&lt;/li&gt;

&lt;li&gt;using spies to verify event bindings and callbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='introducing_the_example_application'&gt;Introducing the example application&lt;/h2&gt;

&lt;p&gt;What web application tutorial would be complete without an example To Do list application? I wouldn&amp;#8217;t want to buck the trend, so for the purposes of the examples here, that&amp;#8217;s what we&amp;#8217;ll use.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re going to create a &lt;em&gt;Todo&lt;/em&gt; Backbone model, with a title, priority rating and done status. We&amp;#8217;ll then create a Backbone collection of these Todo models called &lt;em&gt;Todos&lt;/em&gt;. As we do, we&amp;#8217;ll be writing Jasmine specs to test their behaviour.&lt;/p&gt;

&lt;p&gt;In the third part of this series, we&amp;#8217;ll create router and view objects to handle URL routing and &lt;abbr title='HyperText Markup Language'&gt;HTML&lt;/abbr&gt; rendering respectively.&lt;/p&gt;

&lt;h2 id='setting_up_the_sample_application'&gt;Setting up the sample application&lt;/h2&gt;

&lt;p&gt;The &lt;a href='https://github.com/froots/backbone-jasmine-examples'&gt;sample application can be found on GitHub&lt;/a&gt;. Follow the &lt;em&gt;&lt;a href='https://github.com/froots/backbone-jasmine-examples#readme'&gt;README&lt;/a&gt;&lt;/em&gt; there for instructions on setting up and running the specs.&lt;/p&gt;

&lt;p&gt;Feel free to fork it, clone it and play around with it. It is a Rails application, but the Rails part of it is pretty minimal as it just serves &lt;abbr title='JavaScript Object Notation'&gt;JSON&lt;/abbr&gt; responses to the Backbone application. In fact, if you run the application, nothing much happens, although you should be able to use the rails scaffolding at &lt;code&gt;/todos&lt;/code&gt; to create &lt;em&gt;Todo&lt;/em&gt; models and then fetch them using &lt;code&gt;/todos.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='running_the_spec_suite'&gt;Running the spec suite&lt;/h2&gt;

&lt;p&gt;To run your Jasmine specs, you can either run &lt;kbd&gt;rake jasmine:ci&lt;/kbd&gt; to use Selenium to run through the spec suite or run &lt;kbd&gt;rake jasmine&lt;/kbd&gt; to start the Jasmine server. The output in the Terminal will tell you what URL the server is running on. Navigating to that URL in a browser will run the spec suite.&lt;/p&gt;

&lt;h2 id='backbone_models'&gt;Backbone Models&lt;/h2&gt;

&lt;p&gt;Backbone models can vary dramatically from simple to complex, depending on the requirements of your application. Here we&amp;#8217;ll be focusing on some common model tasks – instantiation, default values, URLs and validation.&lt;/p&gt;

&lt;h3 id='example_1_basic_instantiation'&gt;Example 1: Basic instantiation&lt;/h3&gt;

&lt;p&gt;Normally, it would not really be necessary to test a simple behaviour such as model instantiation unless you are doing something fancy in your own code. It is easy to get carried away and start testing every little thing just because you can, but you should always ensure that you focus testing on your own code, and avoid directly testing dependencies.&lt;/p&gt;

&lt;p&gt;When you write an application using Backbone, you&amp;#8217;ll inevitably have some closely coupled code, so it can be difficult to know what to test and what to create fakes for. After all, your application objects are mostly extended Backbone objects. A good rule of thumb is to only directly test the extended Backbone object that you are currently focusing on. Where an object depends on the methods of another object, fake only the &lt;abbr title='Application Programming Interface'&gt;API&lt;/abbr&gt;s that you need to on that related object.&lt;/p&gt;

&lt;p&gt;This is a subject that is really best explained by example, so let&amp;#8217;s press on with a simple spec for creating (instantiating) a new model. Yes, we&amp;#8217;ll be writing the specs first, watching them fail hideously, and then writing the code to make them pass in the &lt;em&gt;red-green-refactor&lt;/em&gt; tradition of &lt;abbr title='Test-Driven Development'&gt;TDD&lt;/abbr&gt; and &lt;abbr title='Behaviour-Driven Development'&gt;BDD&lt;/abbr&gt;.&lt;/p&gt;

&lt;p&gt;In a Rails project using the Jasmine gem, new Jasmine spec files are created in the &lt;code&gt;spec/javascripts&lt;/code&gt; folder. However, they can be created wherever you like for your project, as long as the file is referenced by your Jasmine spec runner.&lt;/p&gt;

&lt;h4 id='id1'&gt;&lt;code&gt;Todo.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Todo model&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;when instantiated&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;should exhibit attributes&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;todo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
        &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Rake leaves&amp;#39;&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
        &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Rake leaves&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Running this spec produces the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ReferenceError: Todo is not defined in ... Todo.spec.js (line 6)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, we need to create &lt;code&gt;Todo.js&lt;/code&gt;. In Rails, this goes somewhere in &lt;code&gt;public/javascripts&lt;/code&gt;. I like to create separate folders for models, collections, routers, views and helpers in my Backbone applications to keep things well organised.&lt;/p&gt;

&lt;h4 id='id2'&gt;&lt;code&gt;Todo.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which produces the following when the spec is re-run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Finished in 0.03458 seconds
1 example, 0 failures&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yep, all that was needed was to extend the standard &lt;code&gt;Backbone.Model&lt;/code&gt; object. The attribute handling is done by Backbone. This is why it could be argued that this spec is unnecessary, but it does at least check that your model is available and named correctly!&lt;/p&gt;

&lt;p&gt;Now, onto something slightly more useful.&lt;/p&gt;

&lt;h3 id='example_2_default_values'&gt;Example 2: Default values&lt;/h3&gt;

&lt;p&gt;Backbone allows you to set default values for your models if they are not specified when instantiated. We are going to do this with our &lt;em&gt;Todo&lt;/em&gt; priority values. If the user doesn&amp;#8217;t set a priority, it will be assumed to have a value of 3 (possible values are 1, 2 and 3).&lt;/p&gt;

&lt;p&gt;We need to write another spec. As we are creating a Todo instance for each example, we can move this process into a Jasmine &lt;code&gt;beforeEach&lt;/code&gt; function for the sake of efficiency:&lt;/p&gt;

&lt;h4 id='id3'&gt;&lt;code&gt;Todo.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Rake leaves&amp;#39;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This doesn&amp;#8217;t have a priority attribute, so we can now write the spec after the previous one:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;should set the priority to default&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;priority&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When run, the output is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected undefined to equal 3.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, to write the (very simple) code:&lt;/p&gt;

&lt;h4 id='id4'&gt;&lt;code&gt;Todo.js&lt;/code&gt;&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;defaults&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;priority&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='example_3_url'&gt;Example 3: URL&lt;/h3&gt;

&lt;p&gt;Related to default values are &lt;em&gt;validations&lt;/em&gt;. In Backbone.js, a model is validated when the &lt;code&gt;save()&lt;/code&gt; or &lt;code&gt;set()&lt;/code&gt; methods are called to change attribute values.&lt;/p&gt;

&lt;p&gt;However, Backbone will throw an exception if you try to save a model without a &lt;code&gt;url&lt;/code&gt; property defined, so let&amp;#8217;s look at that first.&lt;/p&gt;

&lt;p&gt;Backbone models don&amp;#8217;t strictly need to have a &lt;code&gt;url&lt;/code&gt; property set, provided that they are a member of a collection that does have a &lt;code&gt;url&lt;/code&gt;. A model&amp;#8217;s &lt;code&gt;url&lt;/code&gt; is its parent collection&amp;#8217;s &lt;code&gt;url&lt;/code&gt; plus the model &lt;code&gt;id&lt;/code&gt;. If it doesn&amp;#8217;t yet have an &lt;code&gt;id&lt;/code&gt; attribute, it is a &amp;#8216;new&amp;#8217; model, and so the &lt;code&gt;url&lt;/code&gt; is the same as the collection&amp;#8217;s by default. In our application, and later in this article, we&amp;#8217;ll create a &lt;em&gt;Todos&lt;/em&gt; collection, which will have a &lt;code&gt;url&lt;/code&gt; of &lt;code&gt;/todos&lt;/code&gt;. So, a &lt;em&gt;Todo&lt;/em&gt; model with an &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;5&lt;/code&gt; will have the &lt;code&gt;url&lt;/code&gt; &lt;code&gt;/todos/5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This pattern follows &lt;abbr title='Representational State Transfer'&gt;REST&lt;/abbr&gt;ful conventions as implemented in Rails 3, but the URL of a model or collection can be set to any string value, or can use a function to generate it each time it is needed.&lt;/p&gt;

&lt;p&gt;Because our model&amp;#8217;s URL depends on the collection that it belongs to, we&amp;#8217;ll need to provide something that can provide this &lt;code&gt;url&lt;/code&gt; property. We haven&amp;#8217;t yet written the &lt;em&gt;Todos&lt;/em&gt; collection, and even if we had, we wouldn&amp;#8217;t want to use it as we wouldn&amp;#8217;t then be testing the &lt;em&gt;Todo&lt;/em&gt; model in isolation.&lt;/p&gt;

&lt;p&gt;There are a number of ways to handle this. For this example, we simply need a single property on the foreign object. The simplest approach is to manually stub the &lt;code&gt;url&lt;/code&gt; property. We then simply associate our &lt;em&gt;Todo&lt;/em&gt; model with our stubbed collection:&lt;/p&gt;

&lt;h4 id='id5'&gt;&lt;code&gt;Todo.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should set the URL to the collection URL&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/collection&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;/collection&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This spec passes without any work required on our part, as Backbone.js is automatically delegating to the collection to retrieve the url.&lt;/p&gt;

&lt;p&gt;This approach is fine if your stub is a simple object or property value. If you are stubbing methods and you need to inspect how the method was called, then you should consider using a Sinon spy, stub or mock. We&amp;#8217;ll get to those later.&lt;/p&gt;

&lt;p&gt;We should write another example for when the model&amp;#8217;s &lt;code&gt;id&lt;/code&gt; is set. We&amp;#8217;ll move the collection stubbing into a &lt;code&gt;beforeEach&lt;/code&gt; function so it is used by both examples without duplication.&lt;/p&gt;

&lt;h4 id='id6'&gt;&lt;code&gt;Todo.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/collection&amp;quot;&lt;/span&gt;
    &lt;span class='p'&gt;};&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;collection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;collection&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;when no id is set&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should return the collection URL&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;/collection&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;when id is set&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should return the collection URL and id&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
      &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;/collection/1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Again, this new spec passes first time without any coding required. The example above also demonstrates using nested describe blocks to break up specs by context. This is a common approach in other BDD frameworks such as &lt;a href='http://relishapp.com/rspec'&gt;RSpec&lt;/a&gt;. Usually, you would use a &lt;code&gt;beforeEach&lt;/code&gt; function in each context block to set up the conditions described.&lt;/p&gt;

&lt;h3 id='example_4_validation'&gt;Example 4: Validation&lt;/h3&gt;

&lt;p&gt;Now that we have a valid URL defined for the model (even if it is mostly coming from the collection), we can write some validation specs.&lt;/p&gt;

&lt;p&gt;The Backbone &lt;code&gt;validate&lt;/code&gt; method is not intended to be called directly, but is something that is called when the model&amp;#8217;s &lt;code&gt;set()&lt;/code&gt; or &lt;code&gt;save()&lt;/code&gt; methods are called. Testing it indirectly in this way means that we can&amp;#8217;t just do a simple input-output test. But, in the tradition of BDD we are testing our code&amp;#8217;s behaviour and not its inner workings.&lt;/p&gt;

&lt;p&gt;When we implement our &lt;em&gt;Todo&lt;/em&gt;&amp;#8217;s view object, the chances are that we&amp;#8217;ll want to display something when a model fails validation, so that the user can correct it. To do this, the view binds to the model&amp;#8217;s &lt;code&gt;error&lt;/code&gt; event, and acts on it. We can do the same thing in our test, so we are also ensuring that the event is fired when we expect. When we bind an event, we pass in a callback function to be run when the event fires. We can use an anonymous spy function as the callback:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;eventSpy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;eventSpy&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The spy will record how it is called so that we can later set our expectations against it in a spec. Let&amp;#8217;s write one that tests that the model is not saved and an error is thrown when the title is empty. Don&amp;#8217;t forget that we still have our &lt;em&gt;Todo&lt;/em&gt; model created in a top-level &lt;code&gt;beforeEach&lt;/code&gt; function.&lt;/p&gt;

&lt;h4 id='id7'&gt;&lt;code&gt;Todo.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should not save when title is empty&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;eventSpy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;eventSpy&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;save&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;eventSpy&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;calledOnce&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toBeTruthy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;eventSpy&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;calledWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
    &lt;span class='s2'&gt;&amp;quot;cannot have an empty title&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toBeTruthy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The expectations are checking that the spy callback was called exactly once, and when it was called, it was called with the &lt;em&gt;Todo&lt;/em&gt; model instance and the expected validation failure message. When we run this spec, it fails as expected and Jasmine outputs the following message (twice):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected false to be truthy.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hmm. Although both failures are accompanied by a stack trace and line numbers, the messages themselves are not very helpful. This is because there are no built in Jasmine matchers for setting expectations on Sinon fake objects, so we are forced to use &lt;code&gt;toBeTruthy&lt;/code&gt;. Fortunately there is a &lt;a href='https://github.com/froots/jasmine-sinon'&gt;Jasmine-Sinon plugin&lt;/a&gt; which provides these custom matchers. Once included in the project, and referenced from &lt;code&gt;jasmine.yml&lt;/code&gt; or &lt;code&gt;SpecRunner.html&lt;/code&gt;, you can re-write your Sinon expectations like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;eventSpy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledOnce&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;eventSpy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;cannot have an empty title&amp;quot;&lt;/span&gt;
&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This spec will now produce these failure messages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected Function to have been called once.
Expected Function to have been called with ...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s better. Now to write the validate method to make this spec pass.&lt;/p&gt;

&lt;h4 id='id8'&gt;&lt;code&gt;Todo.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='nx'&gt;validate&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;attrs&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;attrs&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;cannot have an empty title&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When we run the specs again we&amp;#8217;re all green.&lt;/p&gt;

&lt;p&gt;At this point we would probably want to test that saving a model results in the expected behaviour from our &lt;em&gt;Todo&lt;/em&gt; model. However, we will leave server interactions for later.&lt;/p&gt;

&lt;p&gt;Now, on to testing collections.&lt;/p&gt;

&lt;h2 id='collections'&gt;Collections&lt;/h2&gt;

&lt;p&gt;For our Todo application, we need to create a Backbone.js collection of &lt;em&gt;Todo&lt;/em&gt; models. This collection object will be responsible for loading the current todos from the server, as well as standard list behaviour such as ordering and filtering.&lt;/p&gt;

&lt;p&gt;Firstly, let&amp;#8217;s test that we can add models to the collection.&lt;/p&gt;

&lt;h3 id='example_1_adding_models'&gt;Example 1: Adding models&lt;/h3&gt;

&lt;p&gt;When adding models to a collection, Backbone.js will automatically create model instances of the type specified by your collection. For example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Zoo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;Animal&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;edinburghZoo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Zoo&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;
  &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Panda&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Penguin&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The two object literals passed into the collection constructor will be used to create new &lt;em&gt;Animal&lt;/em&gt; model instances.&lt;/p&gt;

&lt;p&gt;In our case, the &lt;em&gt;Todos&lt;/em&gt; collection will reference our &lt;em&gt;Todo&lt;/em&gt; model prototype, but as we are writing unit specs, we want to isolate the &lt;em&gt;Todos&lt;/em&gt; collection, and fake the &lt;em&gt;Todo&lt;/em&gt; model. A good way to think of it is to pretend that we haven&amp;#8217;t yet created the &lt;em&gt;Todo&lt;/em&gt; model and that the &lt;em&gt;Todos&lt;/em&gt; collection is the first thing in the application to be authored.&lt;/p&gt;

&lt;p&gt;In the model examples, we used a simple handcrafted stub of the collection&amp;#8217;s &lt;code&gt;url&lt;/code&gt; property, because that is all that was required on the collection API. In this case, the collection actually instantiates new models itself, so we&amp;#8217;ll have to stub the model&amp;#8217;s constructor function. This is done by creating a Sinon.JS stub as follows:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Todo&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This looks a little strange, but you&amp;#8217;re simply saying &amp;#8220;create a stub of the Todo method on the window object&amp;#8221;. Because &lt;code&gt;window.Todo&lt;/code&gt; is a constructor function, this is entirely valid.&lt;/p&gt;

&lt;p&gt;Whenever we stub a permanent object, we need to restore it back to it&amp;#8217;s original state at the end of each spec, usually in an &lt;code&gt;afterEach&lt;/code&gt; function:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or simply:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;Todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The next part of creating a stub is to alter what the constructor returns. We could manually craft an object literal to look like a Backbone model, but that would be time consuming and tedious. Instead, we&amp;#8217;ll use a bare &lt;code&gt;Backbone.Model&lt;/code&gt; constructor. This will give us a real backbone model, but not one of our &lt;em&gt;Todo&lt;/em&gt; models.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Todo&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We might expect that this would ensure that our &lt;em&gt;Todos&lt;/em&gt; collection always instantiates a stubbed &lt;em&gt;Todo&lt;/em&gt; model. However, the reference to the &lt;em&gt;Todo&lt;/em&gt; model in the collection has already been set up, so we actually need to reset the &lt;em&gt;model&lt;/em&gt; property of the &lt;em&gt;Todos&lt;/em&gt; collection by calling:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;this.todos.model = Todo&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now when our &lt;em&gt;Todos&lt;/em&gt; collection instantiates a new &lt;em&gt;Todo&lt;/em&gt; model, it will always return the bare Backbone.js model instance we have created.&lt;/p&gt;

&lt;p&gt;We can now write our spec for adding new model literals:&lt;/p&gt;

&lt;h4 id='id9'&gt;&lt;code&gt;Todos.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;when instantiated with model literal&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Todo&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
      &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;returns&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;model&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c1'&gt;// reset model relationship to use stub&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;add&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
      &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='nx'&gt;afterEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todoStub&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should add a model&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should find a model by id&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We haven&amp;#8217;t yet created our &lt;em&gt;Todos&lt;/em&gt; collection, so when we run these specs, we get the following error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ReferenceError: Todos is not defined in .../Todos.spec.js&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So we create our &lt;em&gt;Todos&lt;/em&gt; collection.&lt;/p&gt;

&lt;h4 id='id10'&gt;&lt;code&gt;Todos.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And we have a green spec runner again.&lt;/p&gt;

&lt;p&gt;Once again, adding models is something quite simple that you may not end up testing in your own suites, but the technique of stubbing Backbone object constructors is something you&amp;#8217;ll need to use time and again.&lt;/p&gt;

&lt;h3 id='example_2_ordering'&gt;Example 2: Ordering&lt;/h3&gt;

&lt;p&gt;If you provide a &lt;code&gt;comparator&lt;/code&gt; method in a Backbone.js collection, any models in that collection will be ordered according to the string or integer that is returned from the comparator. In our case, let&amp;#8217;s assume we would like to order by priority, so our comparator will simply return the &lt;code&gt;priority&lt;/code&gt; attribute, and Backbone.js will do the rest for us.&lt;/p&gt;

&lt;p&gt;We can write a spec for this quite easily, but we&amp;#8217;ll need to create a few models to add to the collection. Let&amp;#8217;s do this in a top-level &lt;code&gt;beforeEach&lt;/code&gt; method so that we can have access to the models when needed:&lt;/p&gt;

&lt;h4 id='id11'&gt;&lt;code&gt;Todos.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo1&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Todo 1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;priority&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo2&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Todo 2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;priority&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo3&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Todo 3&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;priority&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s write the spec to test our ordering method:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should order models by priority&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;add&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo3&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toBe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toBe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toBe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todo1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When running this spec, Jasmine outputs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;should order models by priority by default&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;followed by a long expectation output. Here is the &lt;code&gt;comparator&lt;/code&gt; method which we add to &lt;code&gt;Todos.js&lt;/code&gt; to make the spec pass.&lt;/p&gt;

&lt;h4 id='id12'&gt;&lt;code&gt;Todos.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;model&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;Todo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='nx'&gt;comparator&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;todo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;priority&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This example demonstrates that a Backbone collection will take any Backbone model you provide. It does not have to be of the type specified in the collection prototype. The collection does not instantiate any models itself here because it is provided with predefined models. So, again, we&amp;#8217;re not depending on our &lt;em&gt;Todo&lt;/em&gt; model for this spec to work.&lt;/p&gt;

&lt;h3 id='example_3_fetching_models'&gt;Example 3: Fetching models&lt;/h3&gt;

&lt;p&gt;Now for a real challenge: how do we unit test the behaviour of an application when it interacts with a server? These tests are often written either as functional tests using fixture data or by using asynchronous unit tests, using real server responses. This is fine, but functional tests can be slow, difficult to set up, require an application to be running on a web server, and depend upon you having all dependencies available.&lt;/p&gt;

&lt;p&gt;Fortunately, Sinon.JS circumvents these problems by providing the ability to fake server responses. This means your complex asynchronous server interaction code can be tested in a rapid unit testing environment. This is a boon for the web developer who may not have control over the whole system. You can set how you expect the server to respond to your request, and test that your code handles it. You can also test edge cases, error responses, offline handling and other lunacy, all in your unit tests.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll write two specs to test that fetching a &lt;em&gt;Todos&lt;/em&gt; collection results in the correct &lt;em&gt;Todo&lt;/em&gt; models being created on the collection. It is important to test the end points of your application where it interacts with other parts of the system. If we are confident that we are making the request to the back-end correctly then integration will be far less bug-prone and problematic.&lt;/p&gt;

&lt;p&gt;Before we write our specs, we&amp;#8217;ll need to set up our fake server. A fake server is essentially a stub as it replaces the behaviour of a real server, and includes spying features to record the requests that were made. We do this in a &lt;code&gt;beforeEach&lt;/code&gt; function:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fakeServer&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;create&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We also need to restore normality once each spec has run in an afterEach function:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;afterEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now that we have a fake server object, we can set expectations against it and write our first spec. This will check that the request to the server is correct. We won&amp;#8217;t ask the server to respond – we&amp;#8217;ll simply check the request it received.&lt;/p&gt;

&lt;h4 id='id13'&gt;&lt;code&gt;Todos.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should make the correct request&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetch&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;requests&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;requests&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;].&lt;/span&gt;&lt;span class='nx'&gt;method&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;requests&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;].&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;/todos&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When we run this test, Jasmine catches a Backbone.js error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Error: A &amp;#39;url&amp;#39; property or function must be specified in ...backbone-min.js&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is easy to fix, we just add a &lt;code&gt;url&lt;/code&gt; property to our &lt;em&gt;Todos&lt;/em&gt; collection:&lt;/p&gt;

&lt;h4 id='id14'&gt;&lt;code&gt;Todos.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/todos&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The second spec checks that when the server responds, the collection creates models representing the JSON returned. For this we&amp;#8217;ll need to have our fake server respond with some JSON data. We expand our &lt;code&gt;beforeEach&lt;/code&gt; function to include this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fakeServer&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;create&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;respondWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;/todos&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='p'&gt;[&lt;/span&gt;
      &lt;span class='mi'&gt;200&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39;{&amp;quot;response&amp;quot;:&amp;quot;json response here&amp;quot;}&amp;#39;&lt;/span&gt;
    &lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s quite a bit to take in here, but it&amp;#8217;s not a as complex as it looks. The fake server&amp;#8217;s &lt;code&gt;respondWith&lt;/code&gt; method takes three arguments here. The first and second are the &lt;abbr title='HyperText Transfer Protocol'&gt;HTTP&lt;/abbr&gt; request method and URL to respond to. The final argument is an array representing the response that is returned, which itself has three values: the HTTP response code, an object literal of response headers, and a string containing the response body.&lt;/p&gt;

&lt;p&gt;In the above example I have created a very simple JSON response string. However, real JSON responses are often long and complex structures, and we don&amp;#8217;t really want those defined in our specs. For this reason we can create fixtures which can be kept in a separate file and shared between specs as needed. The fixtures can be created as JavaScript native literals and converted to JSON strings when the response is formulated.&lt;/p&gt;

&lt;p&gt;A fixture file might look something like this:&lt;/p&gt;

&lt;h4 id='id15'&gt;&lt;code&gt;fixtures.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixtures&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    
    &lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;valid&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='c1'&gt;// response starts here&lt;/span&gt;
        &lt;span class='s2'&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;OK&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='s2'&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='s2'&gt;&amp;quot;response&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
          &lt;span class='s2'&gt;&amp;quot;todos&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt;
              &lt;span class='s2'&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
              &lt;span class='s2'&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Destroy Alderaan&amp;quot;&lt;/span&gt;
            &lt;span class='p'&gt;},&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt;
              &lt;span class='s2'&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
              &lt;span class='s2'&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Close exhaust port&amp;quot;&lt;/span&gt;
            &lt;span class='p'&gt;}&lt;/span&gt;
          &lt;span class='p'&gt;]&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt; 
    &lt;span class='p'&gt;}&lt;/span&gt;
    
  &lt;span class='p'&gt;};&lt;/span&gt;
  
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We use a &lt;code&gt;beforeEach&lt;/code&gt; function so that the fixture is recreated for each spec (in case an unscrupulous developer modifies it). We then create a group of &lt;em&gt;Todos&lt;/em&gt; fixtures, with one &amp;#8216;valid&amp;#8217; response. In this way we can create similar fixtures for error responses and all sorts of other scenarios. The fixture can then be accessed from within a spec with &lt;code&gt;this.fixtures.Todos.valid&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using the built-in JSON parser in modern browsers, and including Doug Crockford&amp;#8217;s &lt;a href='https://github.com/douglascrockford/JSON-js'&gt;JSON library&lt;/a&gt; to polyfill older browsers, we can convert this fixture into a JSON response body in our &lt;code&gt;respondWith&lt;/code&gt; method:&lt;/p&gt;

&lt;h4 id='id16'&gt;&lt;code&gt;Todos.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixture&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixtures&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;valid&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fakeServer&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;create&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;respondWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;/todos&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='p'&gt;[&lt;/span&gt;
      &lt;span class='mi'&gt;200&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt;
      &lt;span class='nx'&gt;JSON&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stringify&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixture&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That is still a little long, and if you use a lot of &lt;code&gt;fakeServer&lt;/code&gt; responses, it will start to take up a lot of space. Most of the time when testing your Backbone.js application, you will want to provide a valid response with a &lt;code&gt;200&lt;/code&gt; response code, an &lt;code&gt;application/json&lt;/code&gt; content-type and a JSON body. Let&amp;#8217;s write a little helper convenience method, which we can place in a separate file and include in our spec suite.&lt;/p&gt;

&lt;h4 id='id17'&gt;&lt;code&gt;spec-helpers.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;

  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;validResponse&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;responseText&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;
      &lt;span class='mi'&gt;200&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt;
      &lt;span class='nx'&gt;JSON&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stringify&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;responseText&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;

&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Like the fixture data, we put spec helper methods in a &lt;code&gt;beforeEach&lt;/code&gt; function and assign the method to the current scope which is shared across all specs. Our &lt;code&gt;respondWith&lt;/code&gt; call can now be re-written to:&lt;/p&gt;

&lt;h4 id='id18'&gt;&lt;code&gt;Todos.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;respondWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;/todos&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;validResponse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixture&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For the purposes of our spec, we&amp;#8217;ll need to discover the format that the response will take. If you are in control of the back-end then this is easy, and you can ensure that the response is straightforward to handle on the client. However, it is often the case that the server response is not your responsibility, for example if another team member is developing it, or the source is an external API. In these cases you will often need to do some parsing of the JSON response before models are created.&lt;/p&gt;

&lt;p&gt;You can see in our fixture above that the array of &lt;em&gt;Todo&lt;/em&gt; items are accessible from within the response JSON at &lt;code&gt;response.todos&lt;/code&gt;. To point Backbone.js in the right direction we need to write a &lt;code&gt;parse()&lt;/code&gt; method on the &lt;em&gt;Todos&lt;/em&gt; collection. This is called whenever data is retrieved from the server, is passed a response argument, and it must return the array of models representing the collection.&lt;/p&gt;

&lt;p&gt;Our spec for the parse method will use the &lt;code&gt;fakeServer&lt;/code&gt; to respond with the JSON fixture above, and we&amp;#8217;ll check that models have been created as expected.&lt;/p&gt;

&lt;h4 id='id19'&gt;&lt;code&gt;Todos.spec.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should parse todos from the response&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetch&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;respond&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixture&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;response&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fixture&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;response&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;].&lt;/span&gt;&lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We only check one model, but you could enumerate over the fixture and check each model very easily. By inserting &lt;code&gt;this.server.respond()&lt;/code&gt; at the appropriate point in the spec, we are telling the &lt;code&gt;fakeServer&lt;/code&gt; to respond with our pre-canned fixture. Note that we have not needed to write an asynchronous test here, despite the fact we are testing asynchronous callbacks.&lt;/p&gt;

&lt;p&gt;When this is run, Jasmine fails the spec with this message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Expected 1 to equal 4&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We are only getting 1 model because Backbone is assuming that the top level object in the JSON response is a model to be defined within the collection. Let&amp;#8217;s fix that:&lt;/p&gt;

&lt;h4 id='id20'&gt;&lt;code&gt;Todos.js&lt;/code&gt;:&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Todos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Collection&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='nx'&gt;parse&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;res&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;res&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;response&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;todos&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now the collection is receiving an array of model-like object literals, and the spec passes.&lt;/p&gt;

&lt;p&gt;The same approach can be used for faking all the standard CRUD operations you might find in a modern web application. For example, to test that your application is correctly saving new models to the server, you would set up a &lt;code&gt;fakeServer&lt;/code&gt; that expects a &lt;code&gt;POST&lt;/code&gt; request to the &lt;code&gt;/todos&lt;/code&gt; URL, and then call the model&amp;#8217;s &lt;code&gt;save()&lt;/code&gt; method in a spec.&lt;/p&gt;

&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;That concludes our look at testing Backbone.js models and collections. Next time we&amp;#8217;ll look at Backbone.js routers and in particular, views, which represent a particular challenge for unit testing.&lt;/p&gt;
&lt;nav&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href='/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html'&gt;Part 1: Introduction&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;Part 2: Models and Collections&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/04/26/testing-backbone-apps-with-jasmine-sinon-3.html'&gt;Part 3: Routers and Views&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;</content>
    </entry>
  
    <entry>
      <title>Using SquidMan to snoop iOS HTTP requests</title>
      <link href="http://tinnedfruit.com/2011/03/10/using-squidman-to-snoop-ios-requests.html" />
      <updated>2011-03-10T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2011/03/10/using-squidman-to-snoop-ios-requests</id>
      <content type="html">&lt;p&gt;If you need to inspect HTTP requests made by iPhone or iPad applications, a simple approach is to use &lt;a href='http://squidman.net/squidman/'&gt;SquidMan&lt;/a&gt; on your Mac.&lt;/p&gt;

&lt;p&gt;The basic approach is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run SquidMan on your Mac&lt;/li&gt;

&lt;li&gt;Change the proxy settings on your iOS device to point to the SquidMan server&lt;/li&gt;

&lt;li&gt;Start tailing the Squid logs on your Mac&lt;/li&gt;

&lt;li&gt;Use the application you want to inspect&lt;/li&gt;

&lt;li&gt;Watch as requests appear in the log&lt;/li&gt;

&lt;li&gt;Save the logs if needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order for this to work, you&amp;#8217;ll need a Mac and your iPhone or iPad to be connected to the same wireless network.&lt;/p&gt;

&lt;h2 id='install_and_run_squidman'&gt;Install and run SquidMan&lt;/h2&gt;

&lt;p&gt;SquidMan is a simple &lt;abbr title='Graphical User Interface'&gt;GUI&lt;/abbr&gt; front-end for the Squid caching proxy server. &lt;a href='http://squidman.net/squidman/'&gt;Download&lt;/a&gt; the latest version and install it as you would any other OS X application.&lt;/p&gt;

&lt;p&gt;When you first run SquidMan, the Preferences panel will be displayed. You only need to do two little tasks in here.&lt;/p&gt;

&lt;p&gt;Firstly, take a note of the &lt;abbr title='HyperText Transfer Protocol'&gt;HTTP&lt;/abbr&gt; port number that Squid uses. You may need to change this port if you&amp;#8217;re already using it somewhere else on your system.&lt;/p&gt;

&lt;p&gt;&lt;img alt='SquidMan preference panel' src='http://images.tinnedfruit.com/blog/20110310/squidman-preferences.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;Secondly, you&amp;#8217;ll need to provide proxy services for your iOS device. To do this follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On your iPad or iPhone, launch the &lt;em&gt;Settings&lt;/em&gt; application and select the &lt;kbd&gt;Wi-Fi&lt;/kbd&gt; section.&lt;/li&gt;

&lt;li&gt;Under the &lt;em&gt;Choose a Network&amp;#8230;&lt;/em&gt; section you should see your wireless network listed. Touch the blue arrow to the right of the entry.&lt;/li&gt;

&lt;li&gt;If the &lt;abbr title='Dynamic Host Configuration Protocol'&gt;DHCP&lt;/abbr&gt; tab is selected, you&amp;#8217;ll see an &lt;abbr title='Internet Protocol'&gt;IP&lt;/abbr&gt; address listed. Make a note of this.&lt;/li&gt;

&lt;li&gt;Back in the SquidMan preferences, choose the &lt;kbd&gt;Clients&lt;/kbd&gt; tab.&lt;/li&gt;

&lt;li&gt;Click the &lt;kbd&gt;New&lt;/kbd&gt; button to add a host&lt;/li&gt;

&lt;li&gt;Enter the IP address you noted from the iOS device settings and click &lt;kbd&gt;Save&lt;/kbd&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img alt='iPad proxy settings' src='http://images.tinnedfruit.com/blog/20110310/ipad-proxy-settings2.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;Close the preferences pane and click the &lt;kbd&gt;Start Squid&lt;/kbd&gt; button to get going. SquidMan should inform you that Squid is now running.&lt;/p&gt;

&lt;p&gt;&lt;img alt='SquidMan GUI when running' src='http://images.tinnedfruit.com/blog/20110310/squidman.jpg' /&gt;&lt;/p&gt;

&lt;h3 id='change_iphone_or_ipad_proxy_settings'&gt;Change iPhone or iPad proxy settings&lt;/h3&gt;

&lt;p&gt;You first need to make a note of your Mac&amp;#8217;s IP address on the wireless network.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;kbd&gt;Network&lt;/kbd&gt; panel under &lt;kbd&gt;System Preferences&lt;/kbd&gt;&lt;/li&gt;

&lt;li&gt;Open either the &lt;kbd&gt;Ethernet&lt;/kbd&gt; or &lt;kbd&gt;AirPort&lt;/kbd&gt; section depending on how your Mac connects to the network.&lt;/li&gt;

&lt;li&gt;The IP address should be listed there. For the sake of example, we&amp;#8217;ll use &lt;code&gt;192.168.0.102&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img alt='Mac OS X Network preference pane' src='http://images.tinnedfruit.com/blog/20110310/network-preferences.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;You should have an IP address and a port for the proxy server. You can now tell your iPhone or iPad to use this proxy server when it accesses the internet using your wireless network.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Back on your iPhone or iPad with your Wi-Fi settings page still open you should see an &lt;em&gt;HTTP Proxy&lt;/em&gt; section.&lt;/li&gt;

&lt;li&gt;Select the &lt;kbd&gt;Manual&lt;/kbd&gt; tab. You should now see form fields for the Server and Port.&lt;/li&gt;

&lt;li&gt;Enter the IP address of your Mac into the &lt;kbd&gt;Server&lt;/kbd&gt; field&lt;/li&gt;

&lt;li&gt;Enter the SquidMan port value you noted earlier into the &lt;kbd&gt;Port&lt;/kbd&gt; field&lt;/li&gt;

&lt;li&gt;Exit the Settings application&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point you can check that internet access is still working by launching Mobile Safari. If you are getting access denied messages, you need to make sure that Squid is set up to provide access to each device.&lt;/p&gt;

&lt;h2 id='tail_squid_logs'&gt;Tail Squid logs&lt;/h2&gt;

&lt;p&gt;There are two ways you can inspect Squid logs: from within SquidMan, or through the Terminal.&lt;/p&gt;

&lt;h3 id='in_squidman'&gt;In SquidMan&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Simply open the &lt;kbd&gt;SquidMan | Tools&lt;/kbd&gt; menu option or hit &lt;kbd&gt;[COMMAND]-T&lt;/kbd&gt;.&lt;/li&gt;

&lt;li&gt;Click the &lt;kbd&gt;Access Log&lt;/kbd&gt; button. You&amp;#8217;ll need to click this again to manually refresh the logs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The example below shows a sample log from the BBC News app. They appear to have code-named the project &amp;#8216;Moira&amp;#8217;, most likely as a dedication to newsreader &lt;a href='http://en.wikipedia.org/wiki/Moira_Stuart'&gt;Moira Stewart&lt;/a&gt;&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img alt='Access log in SquidMan' src='http://images.tinnedfruit.com/blog/20110310/squid-logs.jpg' /&gt;&lt;/p&gt;

&lt;h3 id='in_terminal'&gt;In Terminal&lt;/h3&gt;

&lt;p&gt;You can easily tail the Squid request logs to see what requests are being made through the proxy as soon as they are made.&lt;/p&gt;

&lt;p&gt;To do this, open a Terminal window and run the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;tail -200f ~/Library/Logs/squid/squid-access.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Whilst the logs will not give you more than the basic details of the request and response, it is enough in most cases to see what is going on behind the scenes of a typical iOS application.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Testing Backbone applications with Jasmine and Sinon – Part 1</title>
      <link href="http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html" />
      <updated>2011-03-03T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon</id>
      <content type="html">&lt;nav&gt;
    &lt;ul&gt;
        &lt;li&gt;Part 1: Introduction&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;Part 2: Models and Collections&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/04/26/testing-backbone-apps-with-jasmine-sinon-3.html'&gt;Part 3: Routers and Views&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;&lt;aside&gt;
  &lt;p&gt;&lt;strong&gt;Update 19th June 2012:&lt;/strong&gt; Minor changes for Backbone 0.9.3&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Update 13th September 2011:&lt;/strong&gt; This series has now been updated to reflect changes in Backbone 0.5.3.&lt;/p&gt; 
&lt;/aside&gt;&lt;aside&gt;
  &lt;p&gt;This article series has been translated to &lt;a href='http://science.webhostinggeeks.com/testing-backbone-app'&gt;Serbo-Croatian&lt;/a&gt; by Anja Skrba from &lt;a href='http://webhostinggeeks.com/'&gt; Webhostinggeeks.com&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id='overview'&gt;Overview&lt;/h2&gt;

&lt;p&gt;This is the first in a series of articles demonstrating how to test a &lt;a href='http://documentcloud.github.com/backbone/'&gt;Backbone.js&lt;/a&gt; application, employing the &lt;a href='http://pivotal.github.com/jasmine/'&gt;Jasmine BDD&lt;/a&gt; test framework and the &lt;a href='http://sinonjs.org/'&gt;Sinon.JS&lt;/a&gt; spying, stubbing and mocking library.&lt;/p&gt;

&lt;p&gt;In this part, we&amp;#8217;ll take a brief look at Backbone, and then move on to an introduction to some of the features of Jasmine and Sinon.JS. Along the way we&amp;#8217;ll look at why these tools are a such good fit for testing Backbone applications.&lt;/p&gt;

&lt;p&gt;If you have never written any JavaScript tests before, you might like to take a look at Christian Johansen&amp;#8217;s &lt;a href='http://msdn.microsoft.com/en-us/scriptjunkie/gg655487.aspx'&gt;recent&lt;/a&gt; &lt;a href='http://msdn.microsoft.com/en-us/scriptjunkie/gg649850.aspx'&gt;series&lt;/a&gt; of &lt;a href='http://msdn.microsoft.com/en-us/scriptjunkie/gg650426.aspx'&gt;articles&lt;/a&gt; over at &lt;a href='http://msdn.microsoft.com/en-us/scriptjunkie'&gt;scriptjunkie&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='backbone_everywhere'&gt;Backbone everywhere&lt;/h2&gt;

&lt;p&gt;In the last few months, Backbone.js has received a fair bit of exposure, with a number of tutorials and one or two high profile implementations.&lt;/p&gt;

&lt;p&gt;Backbone&amp;#8217;s popularity is understandable. It provides a fairly minimal &lt;em&gt;model-view-controller&lt;/em&gt; (MVC) structure to help organise all that complex code, but leaves other choices up to the developer. Unlike rich JavaScript UI frameworks such as &lt;a href='http://cappuccino.org/'&gt;Cappuccino&lt;/a&gt;, it does not provide UI widgets or themes, but leaves the choice of DOM library up to the developer. Backbone has specific support for &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt; or &lt;a href='http://zeptojs.com/'&gt;Zepto&lt;/a&gt; if you include them, but it does not preclude the use of other libraries.&lt;/p&gt;

&lt;p&gt;Backbone&amp;#8217;s MVC structure lends itself very nicely to bottom-up unit testing. The separation of concerns into models, collections, views and routers means that the behaviour of each &amp;#8216;class&amp;#8217; (unit) can be tested in isolation, eliminating many bugs up front, and making debugging far simpler.&lt;/p&gt;

&lt;p&gt;This should be very familiar to anyone who has spent any time testing applications developed with MVC frameworks such as &lt;a href='http://rubyonrails.org/'&gt;Rails&lt;/a&gt; or &lt;a href='http://www.djangoproject.com/'&gt;Django&lt;/a&gt;. There are a number of &lt;a href='http://cukes.info/'&gt;mature&lt;/a&gt; &lt;a href='http://relishapp.com/rspec'&gt;libraries&lt;/a&gt;, &lt;a href='https://github.com/thoughtbot/shoulda'&gt;tools&lt;/a&gt; and approaches designed for unit testing these applications. You&amp;#8217;ll need to write JavaScript tests to ensure that your front-end application code is of as high a quality as your server-side code.&lt;/p&gt;

&lt;h2 id='about_jasmine_bdd'&gt;About Jasmine BDD&lt;/h2&gt;

&lt;p&gt;Jasmine is a behaviour-driven development (&lt;abbr title='Behaviour-Driven Development'&gt;BDD&lt;/abbr&gt;) testing framework for JavaScript, which has been developed with more than a passing nod to the Ruby library &lt;a href='http://relishapp.com/rspec'&gt;RSpec&lt;/a&gt;. As with RSpec, Jasmine allows you to write &amp;#8216;specs&amp;#8217; (not tests) representing a single example of behaviour that you would like your code to exhibit.&lt;/p&gt;

&lt;p&gt;BDD emphasises shared language amongst developers and stakeholders. The ethos of BDD, and the way that specs are written in RSpec and Jasmine encourage developers to focus on testing the &lt;em&gt;external behaviour&lt;/em&gt; of their code, rather than its internal details, with specs that are couched in terms of this shared language. This encourages the developer to always consider the beneficial value of the feature being developed, and focus on delivering it.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re interested in learning more about BDD, then take a look at &lt;a href='http://dannorth.net/introducing-bdd/'&gt;Dan North&amp;#8217;s original BDD article&lt;/a&gt;, or even at the &lt;a href='http://www.pragprog.com/titles/achbd/the-rspec-book'&gt;RSpec Book&lt;/a&gt; which has chapters dedicated to the subject, and is more of a BDD bible than an RSpec how-to.&lt;/p&gt;

&lt;h3 id='specs'&gt;Specs&lt;/h3&gt;

&lt;p&gt;So, let&amp;#8217;s dig in and take a look at what Jasmine specs look like. Here is a rather simplistic example of a spec for a Backbone model using Jasmine:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should expose an attribute&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;episode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A spec is simply a description of the expected behaviour, the code that will result in that behaviour, and one or more expectations that test the behaviour.&lt;/p&gt;

&lt;p&gt;Individual specs should be short and only test one aspect of behaviour. If you find yourself writing a number of different expectations or a spec becomes quite long, then consider breaking it out into other specs. Grouping your specs with suites and using shared set up and teardown functions can help with this.&lt;/p&gt;

&lt;h3 id='suites'&gt;Suites&lt;/h3&gt;

&lt;p&gt;Specs are grouped into Suites, which are defined using the &lt;code&gt;describe()&lt;/code&gt; function. For example, all the specs for the Episode model could be grouped into a suite as follows:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Episode model&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should expose an attribute&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should validate on save&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Suites can also be nested, which is great when you have a lot of specs, as you can organise them into sets of discrete chunks. I like to use a &lt;code&gt;describe&lt;/code&gt; block to wrap specs relating to a particular starting context. This better retains the conversational style of the specs. For example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Episode model&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;when creating a new episode&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should expose the title attribute&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='p'&gt;...&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should have a default parental rating&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='p'&gt;...&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='beforeeach_and_aftereach'&gt;&lt;em&gt;beforeEach()&lt;/em&gt; and &lt;em&gt;afterEach()&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;As in traditional &lt;a href='http://en.wikipedia.org/wiki/XUnit'&gt;xUnit&lt;/a&gt; style testing frameworks, you can optionally specify code to run before and after each test. This is great for ensuring consistent conditions for each test, and for setting up variables and objects to be used in your specs.&lt;/p&gt;

&lt;p&gt;The example below uses &lt;code&gt;beforeEach()&lt;/code&gt; to create a model instance that will be used in each spec.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Episode&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;episode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should expose an attribute&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should validate on save&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
    
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can provide a &lt;code&gt;beforeEach()&lt;/code&gt; and an &lt;code&gt;afterEach()&lt;/code&gt; method for each nested describe that you have in your specs, allowing you to have both general and specific setup and teardown methods tailored for each suite of specs. As you&amp;#8217;ll see in the other parts of this article, this is very handy indeed for reducing repetition and controlling the exact conditions for each spec.&lt;/p&gt;

&lt;h3 id='the_spec_runner'&gt;The spec runner&lt;/h3&gt;

&lt;p&gt;This structure results in specs that are pretty easy for other developers to read and interpret directly, largely because of the description for each spec and the format of the expectation matchers.&lt;/p&gt;

&lt;p&gt;Jasmine also provides a simple spec runner, which is simply an HTML page with a script that will run all the specs you provide. The following shows the output from a suite of specs with a single spec failure:&lt;/p&gt;

&lt;p&gt;&lt;img alt='An example Jasmine spec runner output' src='/images/posts/2011-03-02/jasmine-spec-runner.png' /&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll be introducing some other helpful features of Jasmine in the other parts of this article as we need them, including creating fixtures, working with jQuery and creating your own custom expectation matchers. Now, onto Sinon.JS.&lt;/p&gt;

&lt;h2 id='sinonjs'&gt;Sinon.JS&lt;/h2&gt;

&lt;p&gt;Sinon.JS is a library that provides fake objects – spies, stubs and mocks – for testing your JavaScript code. If you don&amp;#8217;t know what these are, then you aren&amp;#8217;t alone. The use of these constructs in testing JavaScript code is not something that has really caught on just yet. However, if you are developing a rich, complex application such as you might using Backbone, then fake objects are a very useful part of the testing toolset.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.cjohansen.no/'&gt;Christian Johansen&lt;/a&gt;, the creator of Sinon.JS, explains &lt;a href='http://msdn.microsoft.com/en-us/scriptjunkie/gg649850.aspx'&gt;why you would want to use fakes&lt;/a&gt; in another scriptjunkie article. In JavaScript applications, these reasons boil down to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Performance - real DOM manipulation, reliance on timed behaviour and network activity slows tests down&lt;/li&gt;

&lt;li&gt;Isolation - unit tests should focus on as small a piece of functionality as possible, and be de-coupled from unreliable or slow dependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The use of fake objects is a fundamental part of embracing test-driven and behaviour-driven development. They essentially allow code to be tested in isolation from its dependencies. Any &lt;abbr title='Application Programming Interface'&gt;API&lt;/abbr&gt;s or modules that your code under test depends upon can be faked to respond in the way you need for your test. You can also inspect the faked methods to see exactly how they were called during the course of a test.&lt;/p&gt;

&lt;p&gt;Sinon.JS allows you to provide fakes for almost anything. You can fake parts of your own application, specific behaviours within jQuery, the &lt;code&gt;XmlHttpRequest&lt;/code&gt; API itself, or you can even fake JavaScript&amp;#8217;s timer methods to allow for rapid testing code that has timing dependencies, such as animations and timeouts.&lt;/p&gt;

&lt;p&gt;Sinon.JS provides three types of fake object: &lt;em&gt;spies&lt;/em&gt;, &lt;em&gt;stubs&lt;/em&gt; and &lt;em&gt;mocks&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id='spies'&gt;Spies&lt;/h3&gt;

&lt;p&gt;Spies are functions that keep track of how and often they were called, and what values were returned. This is phenomenally useful in asynchronous and event-driven applications as you can send a spy function off to keep track of what&amp;#8217;s going on inside your methods, even if those methods are anonymous or closed off from direct inspection.&lt;/p&gt;

&lt;p&gt;Spies can be &amp;#8216;anonymous&amp;#8217; or can spy on existing functions.&lt;/p&gt;

&lt;p&gt;An anonymous spy is just an empty function with spying features that can be sent off to record how it was used. Like a real spy being sent behind enemy lines with a microphone attached to it&amp;#8217;s chest, the method under test is none the wiser. Here is an example of a spy testing a simple Backbone custom event binding:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should fire a callback when &amp;#39;foo&amp;#39; is triggered&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;// Create an anonymous spy&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;spy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  
  &lt;span class='c1'&gt;// Create a new Backbone &amp;#39;Episode&amp;#39; model&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;episode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Episode&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='c1'&gt;// Call the anonymous spy method when &amp;#39;foo&amp;#39; is triggered&lt;/span&gt;
  &lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
  
  &lt;span class='c1'&gt;// Trigger the foo event&lt;/span&gt;
  &lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;trigger&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
  
  &lt;span class='c1'&gt;// Expect that the spy was called at least once&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;called&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toBeTruthy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; 
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will pass if the spy was called one or more times, no matter how it was called or what the arguments were. However, Sinon provides a number of methods that allow you to be as strict as you like about the number of invocations, and indeed what each invocation looked like, and what the spy returned.&lt;/p&gt;

&lt;p&gt;Spying behaviour can also be attached to an existing method. Hilariously, I like to call these &amp;#8216;moles&amp;#8217;. This is useful to check that some piece of functionality is calling another part of the code as expected. For example, you may want to check that a model&amp;#8217;s &lt;code&gt;save&lt;/code&gt; method makes the correct jQuery &lt;code&gt;$.ajax&lt;/code&gt; call:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should make the correct server request&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;episode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
    &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/episodes/1&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  
  &lt;span class='c1'&gt;// Spy on jQuery&amp;#39;s ajax method&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;spy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;jQuery&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;ajax&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  
  &lt;span class='c1'&gt;// Save the model&lt;/span&gt;
  &lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;save&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  
  &lt;span class='c1'&gt;// Spy was called&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='c1'&gt;// Check url property of first argument&lt;/span&gt;
  &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getCall&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;args&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;].&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;/episodes/1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  
  &lt;span class='c1'&gt;// Restore jQuery.ajax to normal&lt;/span&gt;
  &lt;span class='nx'&gt;jQuery&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;ajax&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='stubs_and_mocks'&gt;Stubs and Mocks&lt;/h3&gt;

&lt;p&gt;Stubs and mocks in Sinon implement all the features of spies, but with some added features. Stubs allow you to replace the existing behaviour of a particular method with whatever you like. This is great for emulating exceptions and error scenarios from external dependencies so you can test that your code will respond appropriately. It also allows you to start development when other dependencies are not yet in place.&lt;/p&gt;

&lt;p&gt;Mocks provide all this, but instead mock an entire API and set built-in expectations on how they will be utilised. Like spies they track how they have been used, and like stubs they respond in a pre-programmed manner according to the needs of the test. However, unlike a spy, the expectations for their behaviour is pre-programmed, and a single verification step at the end will fail if any of these individual expectations are not met.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll explore stubs and mocks as they needed in the other parts of this article.&lt;/p&gt;

&lt;h3 id='fake_ajax_and_fake_servers'&gt;Fake Ajax and fake servers&lt;/h3&gt;

&lt;p&gt;Sinon is not limited to spying on and stubbing plain functions and methods. It also provides shortcuts for faking Ajax responses. This means you can test your code in complete isolation from your JSON data source, and don&amp;#8217;t depend on a running a web application in order to run your spec suites. Furthermore, you can test that your application responds appropriately when it strays from the happy path, including invalid JSON and various HTTP response codes.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a simple example of a spec for a Backbone model&amp;#8217;s &lt;code&gt;fetch&lt;/code&gt; method that uses a fake server to respond to Ajax requests:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Episode model&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;beforeEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fakeServer&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;create&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='nx'&gt;afterEach&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;restore&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;should fire the change event&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;callback&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;sinon&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;spy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    
    &lt;span class='c1'&gt;// Set how the fake server will respond&lt;/span&gt;
    &lt;span class='c1'&gt;// This reads: a GET request for /episode/123 &lt;/span&gt;
    &lt;span class='c1'&gt;// will return a 200 response of type &lt;/span&gt;
    &lt;span class='c1'&gt;// application/json with the given JSON response body&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;respondWith&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/episode/123&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;200&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39;{&amp;quot;id&amp;quot;:123,&amp;quot;title&amp;quot;:&amp;quot;Hollywood - Part 2&amp;quot;}&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;

    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;episode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Episode&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;&lt;span class='p'&gt;});&lt;/span&gt;
    
    &lt;span class='c1'&gt;// Bind to the change event on the model&lt;/span&gt;
    &lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;change&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;callback&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    
    &lt;span class='c1'&gt;// makes an ajax request to the server&lt;/span&gt;
    &lt;span class='nx'&gt;episode&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fetch&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; 
    
    &lt;span class='c1'&gt;// Fake server responds to the request&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;server&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;respond&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; 
        
    &lt;span class='c1'&gt;// Expect that the spy was called with the new model&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;callback&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;called&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toBeTruthy&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;callback&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getCall&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;args&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;].&lt;/span&gt;&lt;span class='nx'&gt;attributes&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
        &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='nx'&gt;title&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Hollywood - Part 2&amp;quot;&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
    
  &lt;span class='p'&gt;});&lt;/span&gt;

&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This spec can be made to pass with this simple Backbone model:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;Episode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
  &lt;span class='nx'&gt;url&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/episode/&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There is more to Sinon that we haven&amp;#8217;t covered here. In particular, fake timers are very useful for testing time-dependent functionality such as animations without slowing down your tests. Check out the full documentation.&lt;/p&gt;

&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;In the bleeding-edge world of Backbone applications, complex asynchronous and interdependent behaviours can cause any developer a major headache. Backbone helps developers to structure their code into small, self-contained models, collections, views and routers. But this is really only half the battle. Without well-tested code there will be a greater number of undetected bugs, and those that are discovered will be harder to track down. Other team members may unintentionally break your code, or simply misunderstand its purpose.&lt;/p&gt;

&lt;p&gt;In the second part of this article, we will move on to actually testing some Backbone models and over time we&amp;#8217;ll build up a simple working application with a suite of specs to go with it.&lt;/p&gt;
&lt;nav&gt;
    &lt;ul&gt;
        &lt;li&gt;Part 1: Introduction&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html'&gt;Part 2: Models and Collections&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href='/2011/04/26/testing-backbone-apps-with-jasmine-sinon-3.html'&gt;Part 3: Routers and Views&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/nav&gt;</content>
    </entry>
  
    <entry>
      <title>Git config shortcuts for GitHub</title>
      <link href="http://tinnedfruit.com/2011/02/18/git-config-shortcuts-for-github.html" />
      <updated>2011-02-18T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2011/02/18/git-config-shortcuts-for-github</id>
      <content type="html">&lt;p&gt;&lt;a href='http://lenary.co.uk'&gt;Sam Elliott&lt;/a&gt; has posted some neat Git config tricks that allow some nice shortcuts for GitHub and Heroku:&lt;/p&gt;
&lt;script src='https://gist.github.com/833086.js?file=gitconfig.ini'&gt; &lt;/script&gt;
&lt;p&gt;This allows you to use shortcuts for cloning repositories:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;git clone github:lenary/guides.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and gists:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;git clone gist:806037
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;#8217;m off to put these in my &lt;code&gt;.gitconfig&lt;/code&gt; now.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Jasmine matchers for Sinon.JS</title>
      <link href="http://tinnedfruit.com/2011/02/14/jasmine-matchers-for-sinonjs.html" />
      <updated>2011-02-14T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2011/02/14/jasmine-matchers-for-sinonjs</id>
      <content type="html">&lt;p&gt;I have written a &lt;a href="https://github.com/froots/jasmine-sinon"&gt;small plugin&lt;/a&gt; for the &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine BDD JavaScript testing framework&lt;/a&gt; to allow for better integration with the &lt;a href="http://sinonjs.org/"&gt;Sinon.JS&lt;/a&gt; spying, stubbing and mocking library.&lt;/p&gt;
&lt;p&gt;Using Sinon.JS with Jasmine means you end up writing slightly unhelpful expectations. Here is a simple spec involving a Sinon spy:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;em&gt;jasmine-sinon&lt;/em&gt; plugin creates custom matchers for Jasmine, so that you can do this instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This means that your specs read better, but you also get better failure output from the Jasmine spec runner. Instead of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Expected false to be truthy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;the output is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Expected Function to have been called with 'foo'.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The plugin is at version 0.1, and needs some further testing. It is also missing any exception matchers. Please fork at will.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/froots/jasmine-sinon"&gt;Jasmine-sinon plugin&lt;/a&gt; on Github.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Why web professionals should avoid professionalism</title>
      <link href="http://tinnedfruit.com/2011/02/03/why-web-professionals-should-avoid-professionalism.html" />
      <updated>2011-02-03T00:00:00+00:00</updated>
      <id>http://tinnedfruit.com/2011/02/03/why-web-professionals-should-avoid-professionalism</id>
      <content type="html">&lt;p&gt;Clay Shirky's book &lt;em&gt;Here Comes Everybody&lt;/em&gt; is over two years old now. So of course I am just reading it now - in fits and spurts - to make sure that my hastily formed opinions are as out of date as possible.&lt;/p&gt;
&lt;p&gt;Shirky talks about professionalism in journalism in Chapter 3 (&lt;em&gt;Everyone is a Media Outlet&lt;/em&gt;), arguing that traditional structures such as formal education, training and organisational membership designed to maintain professional standards are the very things that suppress innovation and progression:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"... the professional outlook can become a disadvantage, preventing the very people who have the most at stake &amp;ndash; the professionals themselves &amp;ndash; from understanding major changes to the structure of their profession."&lt;/p&gt;
&lt;cite&gt;—Clay Shirky&lt;/cite&gt;
&lt;/blockquote&gt;
&lt;p&gt;This sentence expressed for me why I am thankful for belonging to a relatively informally structured profession, compared to say, architecture or law. Those traditional professions use traditional means to protect their reputation and standards. When hiring or talking about their own professional effectiveness, most web professionals that you care to talk to will generally eschew formal qualifications, organisational membership and so on, in favour of a loose set of evidence-based norms - or in other words, cool shit you've made.&lt;/p&gt;
&lt;p&gt;When was the last time you heard someone mention their masters degree in Interactive New Media Interweb Technologies when giving a talk, or when introducing themselves at an unconference? No, it's all "Oh, you're that bloke that wrote flibFlab.js - I use that every day!"&lt;/p&gt;
&lt;p&gt;In our profession, new talent can gain recognition within a very short space of time, merely by designing or coding wickedorsum stuff and putting it on Dribbble, GitHub or HackerNews. With more companies apparently hiring &lt;a href="http://ozmm.org/posts/who_we_hire.html"&gt;based on someone's public output of work&lt;/a&gt;&amp;nbsp;(even &lt;a href="http://www.hackdiary.com/2010/02/10/algorithmic-recruitment-with-github/"&gt;algorithmically&lt;/a&gt;) rather than their work history, the traditional barriers of experience, education (to a certain degree) and Not Knowing the Right Person have broken down. This is why it is easier to find good people on GitHub than on LinkedIn, and why recruitment consultants plague the latter and not the former.&lt;/p&gt;
&lt;p&gt;All this is pretty self-evident. But my main point is this: in a rapidly moving profession with informal and shifting norms and standards, the old guard better keep moving along or they'll find they've been shown up rather easily by those with more talent, audacity and, to be fair, time on their hands. In more traditional &lt;em&gt;professional&lt;/em&gt; professions, simply having the job you've got and maintaining a baseline of suitable behaviour and quality is enough to keep you exactly where you are, whilst fostering just the right amount of status anxiety to keep you sharp. How dull.&lt;/p&gt;
&lt;p&gt;As the costs of building and shipping stuff falls, us old giffers that have been doing this stuff since 1995 should find ourselves losing more of our excuses for not shedding our pride and actually producing some real stuff of our own. Hence this blog, and hence some other stuff I want to get out there that I'm working on, and trying to fit around raising a family and getting some sleep. It's either this or kick myself upstairs into a&amp;nbsp;moribund management career tinged with regret. I enjoy learning and hacking around too much for that.&lt;/p&gt;
&lt;p&gt;In short then, make fun stuff and keep on trucking, old man.&lt;/p&gt;</content>
    </entry>
  
</feed>
