043 JSJ Sinon.JS

Download MP3



00:45 - Christian Johansen


Mocks Aren’t Stubs: Martin Fowler


  • js-test-driver 24:17 - Other Mocking Libraries
  • mockjax 26:24 - Mocking Properties 27:22 - Matchers 30:46 - Sinon.JS Gotchas 33:10 - State of Test-Driven Development in JavaScript
  • Strategies for Testing



MERRICK:   Classy guy. [Hosting and bandwidth provided by the Blue Box Group. Check them out at Bluebox.net.] [This episode is sponsored by Component One, makers of Wijmo. If you need stunning UI elements or awesome graphs and charts, then go to Wijmo.com and check them out.] JAMISON:   Hello friends. Welcome to JavaScript Jabber. This is Episode number 43. Today, we have Joe Eames. JOE:  Howdy! JAMISON:   Merrick Christensen. MERRICK:  Hey guys! JAMISON:   And Christian Johansen. And also me, Jamison Dance. But Christian is the special guest today. Do you want to talk a little bit about yourself? Introduce yourself for those of us that don’t know you? CHRISTIAN:   Yeah, sure. First of all, hi! I'm in Oslo, Norway up in the cold north. So, I wrote a book about testing JavaScript a couple of years back called ‘Test-Driven JavaScript Development’. And I've done a few open source libraries. Perhaps the one that most people know about is Sinon.JS. And currently, I work at Gitorious.org. So, that’s the brief introduction about me, I guess. JAMISON:   Great! Chuck is gone today. He’s at CES, I believe. So, that’s why I'm filling in for him. I think we want to talk mainly about Sinon.JS today. Do you want to just give an overview of it? CHRISTIAN:   Sure. JAMISON:   For those who have never heard of Sinon.JS, what is it? CHRISTIAN:   Sinon.JS is a stubbing and mocking library which means that when you're writing automated tests for your JavaScript, Sinon provides a tool kit to help you test functions and callbacks and stuff like that, to track how they're being used throughout the system. And then, it also provides some utilities to test asynchronous stuff through timers, like Set Time Out and Set Interval and those kinds of things. And it also has a fake XMLHttpRequest implementation. So, it allows you to test your client side JavaScript completely decoupled from the server and it gives you an API to mimic the role of the server in your tests. So, you can focus a test on how the client side reacts to various kind of behavior from the server. JAMISON:   So, you talked about stubbing and mocking. And I think, that means we have to get into the hairy discussion of the difference between stubs and mocks? MERRICK:   And spies. JAMISON:   And spies, yeah. Do you want to explain that a little bit? CHRISTIAN:   Sure. I can explain my take on it because I know there are more than just mine. MERRICK:   Sure. CHRISTIAN:   I'm using the terminology pretty much like Martin Fowler did and he has a famous article called ‘Spies are Not Mocks’ or something like that. So, the basic principle implemented in Sinon is that a spy is a function that just records information about how it’s being used. If you call it, it sets a flag, called and it counts how many times it’s been called, what kind of argument you cast into it and so on. And basically, that’s all it does. And then, a stub builds upon that concept but allowing you to also control what it does. So, you can create a stub and then you get a function object that will record everything just like a spy. And then, you can tell it to return certain values or if it receives these arguments, then throw an exception and so on. And then a mock builds upon that again where you can also build in expectations. So, you can tell the mocks that. So, if your call more than two times, throw an exception immediately. That’s the rough cut of it, I think. JAMISON:   That’s amazing. I guess I misunderstood what stubs were. I thought stubs were just basic dumb things that you just specify like a dummy return value for a function or a dummy value for an object or something. Is there a technical name for that? Or you just need to pass in some dependency and you just always want it to return to like 11. What do you call that? CHRISTIAN:   I call that a stub. JAMISON:   Okay. CHRISTIAN:   That’s what I typically use the Sinon stubs for. But they also take on the spy [crosstalk] JAMISON:   And they give you more than that. CHRISTIAN:   Yes. You can also ask them afterwards like, “Were you called more than three times,” or whatever because they just inherit the spy interface. JAMISON:   Sure. MERRICK:   Was there other mocking libraries that you used as kind of a starting point and a reference point for when you created Sinon or did you just like forage off into the wilderness? CHRISTIAN:   Not really, because at some point I thought, “Hey, should I write a stubbing and mocking library?” And then I thought, “No. We probably already have tons of those. So I'm not going to do that.” Then I started looking around and there really wasn’t any alternatives for JavaScript that were any good at that time. So, as I was writing the book, I got kind of tired of repeating the same manual stubs all over the place. I was writing stubs and spies like manually just the way they are in Sinon. And it just started like I extracted the basic stub creating function into a file that I started sharing around. And I figured, maybe we should make a library out of this. So, apart from that, I've been using Mocha in Ruby. So I guess, this was what kind of inspired in part by that. But it’s really a different kind of API, I think. MERRICK:   So, what background did you have and history did you have with testing, unit testing, and mocking when you kind of embarked on this process, just Ruby? CHRISTIAN:   Yeah, mostly Ruby. But I've also done a lot of testing with JavaScript. So, for stubs and stuff like that in JavaScript, I just always did that by hand because functions are easy to create with JavaScript, right? So, I don’t know. I've been testing JavaScript in Ruby for quite a few years before I started writing the library. I guess I started working on Sinon in 2010, maybe late 2009. So, the experience was just working on various apps and writing tests for them with various kinds of test frameworks throughout the years. MERRICK:   So, you don’t have any experience with the mocking library from a strictly typed language like Java or something like that? CHRISTIAN:   No, actually not. I've written tests for Java but I've never used any of the mocking frameworks. MERRICK:   Interesting. Yeah, there’s this huge disparity between mocking and strictly typed languages and mocking and these loosely typed languages. JAMISON:   What do you mean disparity? Like the people don’t do it as much or the tools? MERRICK:   Building the tools. Obviously, they do it a lot more in strictly typed languages than they do in -- well, I don’t know. Ruby is pretty heavily tested, right? But JavaScript is like -- meeting somebody that tests JavaScript is like finding a unicorn. JOE:   I think too with the strictly typed languages, mocking frameworks have it a little bit easier because they just need to honor an interface, right? MERRICK:   Yeah. JOE:   But whereas in JavaScript, you kind of have to like fore in the properties and replace them accordingly or do ones that are explicitly asked to stop? MERRICK:   Right. Is mocking in JavaScript pretty much like the mocking in Ruby? CHRISTIAN:   I guess so, in some ways. Actually, I think there’s a difference because in JavaScript, you have proper first order functions, right? In Ruby, you typically always have classes and object. So, I think there’s a little bit more involved to do mocking, at least for one on one function in Ruby. Sinon only focuses on functions. If you want to stub a whole object, there’s a couple of tools for that. But really, it encourages you to just make an object literal and define spies for the functions that is needed for the current test. MERRICK:   Would say Sinon does spy for that, in particular values? CHRISTIAN:   It depends on what you're using it for. If you needed any other functions to call a call back or return a value, then you’ll use a spy. If you don’t need it to do anything -- sorry, use a stub. And if you don’t need it to do anything, then use spy. MERRICK:   Okay, cool. JAMISON:   I have a question on this mocking and this testing in general. I haven't done a ton of it, I've kind of dabbled in it and the little bit that I've done, it feels like I've spent a lot of time re-implementing the code that I'm trying to test to make sure that everything is all stubbed out correctly. Does that mean I'm doing it wrong? Is that just a hump I have to get over? Or do you have any suggestions to avoid that feeling? CHRISTIAN:   It probably means that something is not the way it should be. Typically, the way I use spies and stubs is supposedly to test the communication between objects or functions or whatever. You're not really supposed to re-implement the logic. In some cases, I would think that you’ll end up re-implementing logic if your test is too big, if you're trying to achieve too many things at a test. And the solution to that is to build smaller tests. Focus on just one behavior at a time and then use a really simple stub that forces your code through that path. JAMISON:   That makes sense. CHRISTIAN:   Yeah. MERRICK:   Yeah. CHRISTIAN:   Typically, if you have some API that takes in a callback of some sort, then you can set up one test that says, “What happens if this callback returns the number 42?” And the next test can be, “What happens if this function throws an error?” But you have to split them up like that because if you don’t, then you’ll end up, like you said, re-implementing logic within your tests. And then, you're not really testing anything. You just have a really elaborate way of doing the same code twice and no way of knowing if it really works. MERRICK:   Sure. JOE:   So, I'm kind of curious about the history of Sinon.JS. Once you’ve published it, you made a lot of changes and enhancements to it based on community feedback? Or did you feel like, did you end up kind of really getting it right, right from the beginning? CHRISTIAN:   I think I ended up getting it right enough. [chuckles] So, I released like a pre-release version as I was writing the book because I wrote the library at the same time I wrote the book. And then, I decided that before this book is on sale, I have to get this thing into 1.0. And I want it to be stable because the API is briefly presented in the book and I wanted it to not break. Like, if you pick up the book, then the first week, I would want the library to still work. So, I spent a lot of time thinking about the design before I handed off the manuscript of the book. So, I was kind of sure that I had what I wanted. And then I call it 1.0 right before the book came out. And now, we’re at 1.5 and there’s been no breaking changes since 1.0, at least no intentional breakages. [laughter] MERRICK:   Semantic versioning. CHRISTIAN:   Yeah, right. Semantic versioning for the win. And there's been some additions after that. But mostly, I've been pretty happy with it for a long time. So, other people have added more to it during the last year than I did. JOE:   I was just going to say it’s cool to have good community involvement. CHRISTIAN:   Yeah, definitely. I'm very happy about that. JAMISON:   I wanted to ask you about the fake XHR thing. Do you just override the Windows XHR property and just give it something that has a compatible interface you could list it on or how does that work? CHRISTIAN:   Yeah. So, first of all, I implemented the XMLHttpRequest spec in JavaScript. And then, there's a function that takes over the global XMLHttpRequest object but that’s not enough because it also has to work in IE. So, in IE, you typically have to also override Active X objects and it has a really weird API because you say, “Active X object.” And then, you pass in a string to specify what API you're using. So, that means I have to override the Active X object and only override it if the argument is XMLHttp or any of the other ID’s that signify XHR. So, it’s a little bit messy, but it works for the most part. JAMISON:   This is a cool idea. MERRICK:   It’s brilliant. JOE:   Since you're talking already about mocking the XHR, let’s talk about Mocking the Clock. CHRISTIAN:   Yeah, sure. It’s just an idea that I actually stole from someone else. It was implemented in JsUnit which is, as far as I know, the first ever JavaScript testing framework. I don’t know when they got it but I discovered it by chance at some point. And I thought, “This is a cool idea. I want to steal this.” And my initial attempt was to borrow their implementation. I don’t really remember why but it wasn’t really portable. So, I ended up writing it over again. But it’s the same principle. So, I defined four functions; Set Time Out, Set Interval, Declared Time Out, Declared Interval. And then, I have a function to copy those four functions into the global namespace and revert them again if you need to restore the actual timers. That’s actually the hardest part. So, for that to work properly in IE, you have to load two files because it’s really, really hard to make Set Time Out writable while still keeping a reference to the original function. JOE:   Oh, why is that? Do you know? CHRISTIAN:   [chuckles] If I’d known, I would have gladly explained but I'm not really sure. So, in IE, Set Time Out is not writable by default. So, you cannot say, “Window.SetTimeOut=something else.” But you can make a function declaration called Set Time Out that will make it writable. But that would also lose the original reference to the function. And because the function declaration is hoisted, you lose it for good. So, that’s why we’re using two files to get that to work. MERRICK:   Oh, wow! CHRISTIAN:   [laughs] Yeah, it’s messy. MERRICK:   It’s crafty, though. JOE:   So, one of the things that I thought was coolest about mocking the clock was the ability to do it when dealing with date objects. Can you talk a little bit about that? CHRISTIAN:   Yeah. That’s the same thing again where overriding the data object and initialize the fake timers, you initialize it with a starting time which defaults to just zero. And when you say ‘clock.tick1500’, then it would call any callback schedule with Set Time Out within the next 1500 milliseconds. But then will also update whatever dates dub now is. So, if you create date objects, they will have the time corresponding to how much you’ve ticked the clock manually. JAMISON:   Oh, that’s really cool. CHRISTIAN:   So, if you create a date and then you tick the clock 1500 milliseconds forward and then create a new date object that will do 1500 milliseconds apart. MERRICK:   Wow! I haven't actually taken advantage of that. But I imagine that you’ve found that to be really valuable. CHRISTIAN:   Yeah. I used it recently for one of the code examples in the book where implementing like a long polling AJAX thing to do a chat application. And the long polling implementation, the dates were kind of important for figuring out when to fire the next request and so on. And they also used date objects to kill requests after a certain amount of time. So then, I needed the date objects to behave properly. JOE:   Cool. Since you mentioned the book again, can you talk a little bit about the book? I’d like to hear about why you wrote it, the process of writing it, what you learned from it, what interesting things you discovered about it. CHRISTIAN:   Yeah. [chuckles] The why is actually the publisher contacted me, asked if I wanted to write a book. I guess, I blogged a lot at that time. And then, the publisher stumbled upon my blog, asked if I wanted to write a book. And I thought, “Yeah, I do.” And so, I set aside some time and started writing. I knew it was going to be about testing because that was what I've been writing about for like a year in advance. Anyway, so, it’s a topic that I've been very interested in. And the process, it’s a lot of hard work. It takes a lot of time. And I learned a lot about what the book is about because when you're writing about these things, you have to really do a deep dive to make sure you have every base covered, that you present things properly, everything’s correct. I went over the [inaudible] spec several times while writing it to make sure that everything was technically correct. This really felt like a bit of a research project even if the book is not very scientific or anything. But for me, it was like doing a lot of research and then sitting down, writing down some things, more research, editing, and then, having an argument with my technical reviewers. [laughter] JAMISON:   Did you win by saying, “Hey, I'm the expert. I wrote the book.” CHRISTIAN:   Uhhh, not really. [laughter] CHRISTIAN:   But I had some excellent technical reviewers. Among them, I had Andrea Giammarchi. You may know him as Web Reflection, on Twitter and other places. And he’s a man of strong opinions. JAMISON:   [laughs] CHRISTIAN:   And he’s also very, very smart. But we had some differences in how he prefers certain things. We had some interesting arguments while I was working on the book. But I learned a lot from it and it was really fun working with him. JOE:   Awesome! So, how long have you been doing Test-Driven Development? CHRISTIAN:   I’d say maybe six years, something like that. What year are we now? Maybe seven. Yeah, seven years. JOE:   What caused you to get into it? CHRISTIAN:   I’d have to say probably Rails, I think, because I did some testing prior to that. But I think Rails really pushed me into it, the way that I'm doing it now anyway. JOE:   So, what industry luminaries do you take inspiration from specifically when writing the Test-Driven Development? CHRISTIAN:   Well, obviously Kent Beck. I learned a lot from him. After Rails kind of got me started, I immediately plunged into a lot of Kent Beck’s material that I’d been looking at briefly before but never studied it over and I learned a lot from him. Also, he’s done some videos for Pragmatic Bookshelf or whatever, those guys. He did some videos. If you haven't seen them, you really should because they're really interesting to watch and just get to watch him work. [crosstalk] CHRISTIAN:   What? JOE:   The Pragmatic Programmers? CHRISTIAN:   Yeah. JOE:   Okay. CHRISTIAN: He did a series of videos for them. You get to just watch him sit there and code and think out loud. And he has a really interesting way of thinking about and approaching problems. So, I learned a lot from him and from like Bob Martin and… JOE:   Bob, Uncle Bob Martin? CHRISTIAN:   Uncle Bob, I mentioned him. But also Michael Feathers. Sort of like the good old guys that kick-started the whole extreme programming thing. MERRICK:   So, what do you most frequently -- I mean, you're obviously using Sinon. I'm wondering what test framework do you typically use it with? CHRISTIAN:   I'm actually also writing my own test framework. [laughter] MERRICK:   Oh, awesome! Any plans for releasing it? CHRISTIAN:   Yeah. So, it’s called Buster.JS. And I'm doing it with a friend of mine. MERRICK:   That’s great. I've used Buster actually. CHRISTIAN:   We started this actually over two years ago. And we had a lot of plans for it, and we still do. But it’s taking a lot more time than we planned to get it stable enough. And I'm using it for the stuff that we do at work, and we have been for quite a while. Before that, I used js-test-driver which works by the same model. It allows you to automate tests from the console through browsers through a server. So, you can hook up to browsers as slaves to a server. And then, you can issue test runs from the command line. You get results from actual browsers but in the console. MERRICK:   Buster also seems to be one of the few that wants to be kind of a full solution. I mean, they have node connectors, AMD, et cetera. CHRISTIAN:   Yeah. So, the original idea was that there are tons and tons of half baked test frameworks for JavaScript stuff that people did through one weekend or whatever. So, we wanted to provide like, if you will, the enterprise version or something that’s more complete. MERRICK:   Sure. That’s very much the feeling I got when I was using Buster. So, are there any other test frameworks that you’ve used that you liked and thought were pretty cool? CHRISTIAN:   I haven't really used that many of them. I’ve never used Jasmine which is a tool I know a lot of people like. I use js-test-driver and then I used the prototype testing framework for some time. But I don’t think I’d recommend that to anyone now. [laughter] CHRISTIAN:   Not that it’s bad. It was good for its time but there are better solutions now. So, I don’t know. I haven't really tested them all a lot. I used YUI test for a little while, as well, and it’s a bit -- I don’t know. It’s not for me. But it’s good stuff, I guess. MERRICK:   In terms of Sinon, it seems like that is one area where there's not really any other options, like people haven't felt a lot of need. Do you know of any sort of, I don’t want to say competitors, but other mocking and stubbing libraries? [crosstalk] MERRICK:   I'm in such a…[crosstalk] JAMISON:   It’s funny, there’s a thousand test frameworks and there’s one mocking framework. MERRICK:   Yeah, and they all recommend Sinon. CHRISTIAN:   [chuckles] I'm glad to hear that. That was kind of what I was hoping for when I started. I worked very hard to make it, Test Framework agnostic. So, it should be easy to integrate into test frameworks. And I was kind of hoping that Sinon would like the engine for other people’s stubbing solutions. And that has happened to a certain degree. So, I know that the test framework that ships with ‘qooxdoo’, the UI framework, they have a stub and mock API which is actually powered by Sinon. MERRICK:   Cool. CHRISTIAN:   Very cool. That’s the kind of thing that I was hoping that it would be used for. And I know that Jasmine has their own thing built-in but some people still seem to prefer Sinon. I haven't used their service, so I wouldn’t really know. But then, the only other one I really know about is something called Mockjax. I don’t have a lot to say about it because I don’t know it very well. But that’s one alternative, I guess. I think that it’s more geared towards mocking objects, whereas Sinon is very focused on functions. MERRICK:   Yeah. And it supports objects as well, in a sense. CHRISTIAN:   I mean, objects are just collections of functions. So, I don’t think that Sinon does anything to keep you from working with objects. It’s just that I don’t think it’s necessary to have a lot of tools geared towards objects because it’s so easy to just make an object literal and stick spies in it. MERRICK:   Yeah. JOE:   So, in a strictly typed language, the mocking frameworks usually have a fairly significant piece that is for mocking properties and not just the methods, whereas Sinon doesn’t mock properties at all. Do you have any plans to take advantage of the ES5’s property getter/setter stuff and provide mocking or stubbing with that? Spying? CHRISTIAN:   I want to say no. [chuckles] We’ll see. There’s no support for getters or setters at this point. And to be honest, I'm not really that much of a fan. So, I’d prefer to not do anything with that for the moment. If someone comes along with a reasonable implementation, I’ll look at it. But I don’t know. I'm really on the fence with getters and setters. I'm not a huge fan. JOE:   Gotcha. One of the other things that I thought was really cool about Sinon is Matchers. And I know that that’s a really distinct feature. I don’t think Jasmine has any concept of Matchers. Could you explain a little bit like what Matchers are and how you came up, why you came up with them and the value of them? CHRISTIAN:   First of all, I'm going to say that I didn’t come up with them at all. The Matchers is one of the several features that were delivered by a guy called Maximilian Antoni from Switzerland. He’s a great guy. And he’s the only other person than me that now has commit access to the main Sinon repository. So, he’s done several things with Sinon and that’s, I think, his biggest addition to the library. And it’s somewhat similar to a concept that we have in the assertions. We ship the Buster that allows you to match objects loosely by some various criteria. For Sinon, that means that you can check that a function was called with some arguments. But you can also enforce some loose constraints like, “I want it to be called with a string and a function.” But you don’t have to say the exact string. And also with functions, it’s really hard to match it unless you can get access to the exact function that was passed in. So, it’s just a way of testing the kinds of things that are being passed around without having to specify exactly what they are. There's also a matcher in there that allows you to partially compare objects like, “I wanted this object to have these three properties, and I don’t really care if they have other properties as well.” JAMISON:   Oh, okay. I'm looking at the example here. That’s what this first one is where you're calling Sinon.match [inaudible] an object that has an [inaudible] property. So, you're saying, “I don’t care what it’s called with as long as it’s same object that has these properties.” CHRISTIAN:   That’s correct. JAMISON:   Oh, okay. That’s cool. MERRICK:   Yeah. And you can be vague, right? You can say that it just has to have these properties and you don’t actually care what the property values are. Or you can actually specify that the properties have to have these values as well, right? CHRISTIAN:   Yeah. MERRICK:   So, like one of the places that I've been bitten a bunch before is verifying a call that came in with a callback. And I had access to the callback, but I ended up wrapping that callback in like a jQuery’s proxy to make sure that it was bound correctly to the right context. And since that was happening somewhere else, I couldn’t get access to the proxy function or the interior function. So, having the ability to match just by, “Hey, it’s just got to be R function,” is just absolutely huge for me. CHRISTIAN:   Yeah. You could do it before too because you always have access to the arguments. So, you could do a type of check but it’s really kind of verbose and ugly. So, I really liked the Matchers because they allow you to be a little bit more descriptive about what you're trying to achieve. It reads a lot better, I think. JAMISON:   I've got to say that the docs are really good. It’s a credit to you, guys. That I feel like almost everything we’ve asked about, we could have just like read in the docs. It’s still great to have you on here. But they're very complete and clear and that’s a big change from some other JavaScript projects, I think. Sometimes, they don’t get documented that well. So, they're great. CHRISTIAN:   Thanks. MERRICK:   Something that’s probably not in the docs, what did you find to be the hardest things to figure out when you were building Sinon? CHRISTIAN:   I think the stuff that I mentioned with overriding Set Time Out and the other Globals while still being able to restore them. MERRICK:   So, basically IE? CHRISTIAN:   Yeah. In short, IE, yeah. Because that is nowhere near as difficult in the other browsers. So, that’s definitely been the toughest part to make that right. Also, I feel that over the past year or so, when I have a lot of contributions from other people, it’s been other kinds of challenges to like keep up and to review stuff properly. We had a couple of -- I did one release where I accidentally broke something. That was kind of a reminder that, “Hey, you need to pay attention when you're not writing the code yourself.” [laughs] So, that’s been a bit of a new situation but it’s definitely manageable. JOE:   So, one of the things that I think you implied early on in the podcast was if you're testing an object, let’s say that that object has two methods, method A and method B. And method A internally calls method B. How do you feel about stubbing out method B just when you're testing method A so you do not actually test method B as well? Are you for that or against that? And the reasons why? CHRISTIAN:   I think I’d have to say that I'm, in principle, against that because I usually never stub out methods on the object that I'm testing. And the reason for that is that if you have a method A that’s calling method B on the same object, and you're stubbing out method B, then really, the test is very implementation specific. So, the fact that it’s calling another function on the same object is really an implementation detail. It’s not part of its public API. So, I’d say that in a situation like that, if you have a need to do that, maybe that’s a signal that your design can be improved somehow. JOE:   Cool. I like that answer. Definitely that’s one of the things that’s been on my mind a lot. How would you say is the state of tester and development in JavaScript today? CHRISTIAN:   I think it’s picking up. It’s probably still not as great as in like -- I think that in the Ruby community, there's been a lot of focus on testing. I guess that with the Node Projects, it’s probably picked up a bit of speed. But I still think that most jQuery plug-ins and code that people use a lot is still, by large, untested. But I haven't measured this recently. This is just my gut feeling and this is how it’s looked every time I looked. There's a lot of test frameworks. There's a lot more test frameworks than there seem to be people using them. [laughter] JAMISON:   The people, they write a test framework and then they don’t test anymore. And they're like, “My job here is done.” CHRISTIAN:   Yeah. [laughter] MERRICK:   That’s when they decide if they want to test. [laughter] CHRISTIAN:   Interestingly, there's also a lot of test frameworks that don’t have tests. [laughter] CHRISTIAN:   But I actually teach a course here in Norway. It’s a bi-monthly thing, three days. I teach people to do TDD with JavaScript. There's a good amount of people showing up for those courses. I think the interest is there but people are not finding time at their day job, I think, to get into it. Because it does take a little bit of time to get comfortable with it, get it into your work flow. So, I think people are scooching it off. JAMISON:   It’s like any new skill, right? When you first try it, you're going to be slower at it. So, I think to some people, they just keep putting it off because it’s not worth it at that time to do lots of testing because it will make them slower for X amount of days or weeks or whatever, to get stuff done now! But hopefully, it pays off in the end. I think another problem is, you mentioned Node. In my experience, it’s been a lot easier to test stuff written in Node than things that interact heavily with the browser and with users. And part of that is just tooling. Like, I've just spent a couple of days getting one of our big frontend apps testable just with unit tests and integration tests. And it’s a giant pain in the butt. And if I didn’t have time dedicated, like set aside to do it, then I would never have done it. So, I don’t know. I hope that situation gets better too. JOE:   I think with Node too, like your script loaders are not asynchronous. So, that’s like one of the biggest things that’s been easy for me in terms of testing Node is that when I require a module, I have it. Do you know what I mean? Whereas, that’s not necessarily the case in browsers. CHRISTIAN:   No. But I think that’s more of an inconvenience than anything else. It shouldn’t really stop you from testing. MERRICK:   Agreed. JOE:   Yeah. CHRISTIAN:   And also, in terms of testing browser code, I definitely agree that coming back to test browser code after the fact is really, really, really hard which is why I think that TDD is such a good fit for JavaScript in the browser because if you're writing tests as you go, then your designs will be completely different. You will automatically have to design your code to avoid browser APIs all the time, right? I think there's a traditional jQuery like ‘cold cowboy mess needs to die’ if you want to make testable code. It doesn’t really work out to just do jQuery, function, and then [expression] throw up lots of code. It doesn’t really take you that far. So, if you want to make it testable, you have to make it modular or you have to modularize your code so that it’s possible to see some kind of API that you can call from your tests. And that’s where I think the biggest problem is today is that people just don’t apply abstractions to JavaScript at all. They just throw stuff together, an event handler here, some AJAX stuff. Boom! Boom! Boom! Here’s my site. JOE:   Let me just store all this state in the DOM. [laughter] CHRISTIAN:   Yeah, right. Use data attributes and store them in there. JOE:   Yes. So, when you're testing in the browser, your strategy is for testing with code that might interact with the DOM. Is that to isolate the DOM code into some other classes and have your logic in a class by itself or do you support DOM testing? Do you actually test the methods that are interacting with the DOM? CHRISTIAN:   Yeah, sure. So, I do both things, I think. I tried to keep the browser specific parts contained to one area of the code and then have as much of the code base as possible free from browser APIs. And that’s actually kind of easy if you have that thought in your head as you're writing the code. And then, I also test the browser parts but I try to at least make them so that they only work in memory like if you have some kind of widget that you pass in the root node. And then, it only works on the root node because then you can construct in memory DOM elements, pass them in and make sure that they’ve been manipulated the way you want, as opposed to having the module use CSS selectors to reach for stuff globally in the document and then munging that. Did that make any sense? JOE:   Absolutely, yeah. It’s funny, I think, testing some of these MVC from like Backbone lends itself really naturally to that because it creates the element in memory first so your rendering kind of sets up your DOM ahead of time? CHRISTIAN:   Yeah, definitely. JOE:   Well, I guess we need to wrap this up, right Jamison? JAMISON:   Yeah. We’re about at the time. So, if you guys have any last things you want to say or ask, go for it. MERRICK:   I just want to pipe in that I think that Sinon is possibly the biggest contribution to testing JavaScript that’s been done in the industry. So personally, I just want to thank you. I think that’s pretty awesome. I was totally jones to have you on here. CHRISTIAN:   Thanks a lot. That’s very nice to hear. JOE:   I’ll echo that sentiment. I've played around with a lot of testing frameworks, but Sinon is the one tool that’s kind of followed me between them. CHRISTIAN:   Glad to hear it. JAMISON:   Alright. Let’s go to the picks. Joe, do you want to start us off? JOE:   You bet. So, my first pick is going to be the movie Jack Reacher. I went and saw this last weekend and they did a really good job. I understand from the book or something, Jack Reacher’s supposed to be like this huge 6’8” guy. So, Tom Cruise was a funny cast for that. But I really think they must have done a really good job with casting other really short actors because… JAMISON:   They gave him some tall shoes or something? JOE:   Maybe. I think the movie was awesome. I loved it; great guy movie, good action but also really interesting kind of plot mystery going on. Also, my other pick is going to be the game, Torchlight II. I picked that up on Steam Sale over the holiday weekend and I've been playing that quite a bit. It’s a lot like Diablo. A little more cartoony but I think the implementation is even a little superior to Diablo but I really liked it. That’s going to be my second pick, Torchlight II. JAMISON:   Jack Reacher feels a little bit like man Twilight. [laughter] JAMISON:   Just throw away like hilariously over the top action stuff. It’s good stuff. Merrick, do you want to go? JOE:   That sounded like an insult to me. [laughter] JAMISON:   Well, I mean, Twilight is great is you like it. Jack Reacher, I've read lots of his books and they're not great literature but they're really entertaining reads. Anyway, Merrick, do you want to go? MERRICK:   Sure. The first thing is the ‘Effective JavaScript’ book by Dave Herman. I just finished reading that last night. And it is the most enlightening JavaScript book that I've read to date. Second would be ‘Rdio’. It’s just a [inaudible] where I stream all my music. It’s incredible. JAMISON:   Sweet. I’ll go next. So, I have three picks. The first one is like five years too late because I guess it’s been going on for a while. But it’s just the TV show, ‘Adventure Time’. I've heard a lot about it but I just never sat down and watched any of it. It’s this kid’s cartoon. It’s kind of like Sponge Bob if it wasn’t really annoying. It’s all these adventures of these two awesome bros and I don’t know. It’s really great at being like friendly, happy humor but still has stuff that’s funny to adults. So, Adventure Time is awesome. My next pick is called ‘How to Implement a Paper’. It’s just this blog post about implementing some algorithms you find in reading papers. They usually don’t give great pseudo code or code at all for their algorithm. They just kind of talk about it and use lots of math. And it can be a little tricky to read the paper about how they actually translate their ideas into code. So, this is a good read about how to do that. And then, my last pick is this blog post about Vim. I use Vim, it’s amazing. There's always more stuff to learn. And it’s just talking about cool stuff you can do with Vim registers. And I learned a few things I’ve never heard of. It’s called ‘Advanced Vim Registers’. And the links to all this stuff will be in the show notes. Alright. Christian, do you want to give us your picks? CHRISTIAN:   Yeah, sure. So, my first pick is going to be a site that a friend of mine does. You mentioned Vim, so we’re Emacs users here in the civilized part of the world. JAMISON:   Oh no! [laughter] JAMISON:   I might accidentally delete your voice in this podcast. [laughter] CHISTIAN:   Yeah! [laughter] CHRISTIAN:   So, my friend Magnar does a site called EmacsRocks.com. And no matter if you use Emacs or not, you should watch his videos. It is like three to five minute videos showing off some crazy stuff you can do in Emacs and he has this really great way of presenting. It’s just good fun to watch. There's also a blog there where he walks you through his Emacs set up in just really short blog posts. So, that’s great. That’s my first pick. My second one is a talk. It’s a bit old but maybe not everyone has seen it yet, by Rich Hickey, who is the author of Clojure, the language. It’s called ‘Simple Made Easy’. And it’s a presentation that every programmer should see, it’s completely awesome. It talks about simplicity and how that does not necessarily mean easy. And it’s just a good talk, you should watch it. And my final pick is ‘Lego, Lord of the Rings’ [chuckles] which is yeah, awesome. It’s Lego guys reenacting the Lord of the Rings movies and it’s just great fun. I play it on Xbox. MERRICK:   So, we bought that game and it’s in the shrink wrap on my mantle waiting for my son to be good at school enough days in a row so we can unwrap it and play it. [laughter] CHRISTIAN:   You have something to look forward to. It’s great fun. MERRICK:   Tonight could be the night if he’s good at school today then, that’s it. I'm going to be playing that tonight. JAMISON:   Well, maybe if you're good at work, you can open it early or something. [laughter] MERRICK:   Yeah, that’s not going to happen. [laughter] JAMISON:   Great! Well, Christian, it was great to have you on here. I'm really glad we got to talk about Sinon. I've used it a little bit but I’ll definitely use it more after hearing about it. So, it’s just cool. CHRISTIAN:   Thanks a lot for having me. JAMISON:   Next week, we are doing our Book Club Episode. We are going to be talking about Effective JavaScript, the book that pretty much everyone has picked at one point or another for the last few weeks. And we’re going to have David Herman, the author on. So, read the book and we’ll talk about it and it will be awesome. JOE:   I have one more pick to throw in at the end. Since you reminded me of something, my Pluralsite course on testing JavaScript is going to be coming out in the next month. And there’s a pretty big module on Sinon on there. So, that should be available around the beginning of February. JAMISON:   Yeah, cool. Sweet! Anything else? JOE:   Nope, that’s it. JAMISON:   Alright. See you, guys. JOE:   Thanks Christian! MERRICK:   Thanks Christian! CHRISTIAN:   Alright!

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.