Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Unit Testing in JavaScript with MVC and QUnit


Published on

While more and more application code move from the back-end to a JavaScript-based front-end, we still need to test this code efficiently. Testing JavaScript is often done using browser automation frameworks, but system-level testing is slow and brittle.

Here we present a way to structure your JavaScript application according to the Model-View-Controller (MVC) design pattern and how this enables us to write unit tests for a large part of the application logic, using a testing framework like QUnit.

Sample source code available at

Published in: Technology
  • Be the first to comment

Unit Testing in JavaScript with MVC and QUnit

  1. 1. Unit Testing in JavaScript with MVC and QUnitLars ThorupZeaLake Software ConsultingJune 14, 2011
  2. 2. Who is Lars Thorup?● Software developer● Coach: Automated testing and other agile practices● Advisor: Assesses software projects and companies● Founder and CEO of BestBrains and ZeaLake
  3. 3. Agenda● Sample application under test● How to use QUnit● Asynchronuous testing● How to use Model-View-Controller● Assumes knowledge about JavaScript● Assumes knowledge about unit testing
  4. 4. JavaScript must be tested in the browser
  5. 5. Example app: Collaborative Dialog● Front end entirely in JavaScript● Back end service methods implemented in C#
  6. 6. How do tests look like?● util.test.html● ok(actual, message)● equal(actual, expected, message)● same(actual, expected, message) ● deep equivalence● raises(expected, function, message)
  7. 7. How to modularize tests?● view.test.html● module(name, fixture)● all following tests will have this being a newly created fixture object with setup() and teardown() run before and after the test
  8. 8. Testing ajax● svc.test.html● call expect(number-of-assertions) to verify that callbacks was actually called● call stop(timeout) before first ajax call● call start() when test is complete ● typically inside ajax callback● if more than one asynchronous call in one test: ● call stop() before each ● call start() in callback of each
  9. 9. Make your JavaScript testable● MVC design pattern: Model - View - Controller● Dependency injection● Isolated testing controller view model svc
  10. 10. View● view.js controller ● injected html ● load html page from the server ● html becomes directly stylable view model● Responsibilities svc ● manipulate html ● generate html from templates ● dispatch events to listeners ● nothing more!● References ● a set of event listeners (typically the controller)
  11. 11. Controller● controller.js controller● Responsibilities ● handle all events from the view model view ● poll model for change events if relevant svc ● convert events to commands against the model ● repaint strategy ● error handling strategy● References ● the model (to execute commands, polling) ● the view (to do repainting)
  12. 12. Model● model.js controller● Responsibilities ● cache state to minimize round view model trips ● provide view and controller with a useful interface of the svc data model● References ● the service proxy
  13. 13. Service Proxy● svc.js controller● Responsibilities ● provide a javascript api view model mapping of the server api● References svc ● the physical server via ajax
  14. 14. Testing the view● view.test.js test● Inject ● controllerStub ● canvas controllerStub● Invoke methods view● Assert ● canvas ● controllerStub
  15. 15. Testing the controller● controller.test.js test● Inject ● viewStub controller ● modelStub● Invoke methods viewStub modelStub● Assert ● viewStub ● modelStub
  16. 16. Testing the model● model.test.js test● Inject ● serverStub model● Invoke methods● Assert svcStub ● state ● serverStub
  17. 17. Testing the service proxy● svc.test.js test● Invoke methods● Assert ● results svc
  18. 18. Callbacks in JavaScript● Ajax means asynchronous ● Server methods become asynchronous ● Model methods become asynchronous ● To return a value you must supply a callback● Error handling ● Include in every callback
  19. 19. this in JavaScript● Avoid using this in callbacks, since this probably refers to the object that invokes the callback, not the object that contains the code for the callback.● Instead use jQuerys $proxy() method ● Example: controller.js
  20. 20. Bootstrap● bootstrap() function ● see collabForm.js● creates model, view and controller and ties them together● start polling engine (if relevant)● called by onload or $(document).ready() ● see Index.aspx
  21. 21. Run tests on build server● QUnit tests needs to run in a browser● On WIndows, the browser requires a WinStation ● So the build server must be logged on at all times for this to work● Hard to avoid tests that hang● Consider running tests manually instead
  22. 22. Testing the backend● Test your webservices● Use QUnit and assert on the returned JSON ● Or use your backend testing tool
  23. 23. Real World Example● WizerPro, in JavaScript, using MVC pattern
  24. 24. Further reading● Documentation ●● Book ● "Test-Driven JavaScript Development", Christian Johansen● QUnit Presentation ●
  25. 25. Future meetups● TDD coding dojo with C++ and Ruby ● Thursday June 24th (in a week!)
  26. 26. Feedback● Give your evaluation at