SlideShare a Scribd company logo
Unit Testing in JavaScript with MVC and QUnit
Lars Thorup
ZeaLake Software Consulting


June 14, 2011
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
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
JavaScript must be tested in the browser
Example app: Collaborative Dialog
●   Front end entirely in JavaScript

●   Back end service methods implemented in C#
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)
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
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
Make your JavaScript testable
●   MVC design pattern: Model - View - Controller

●   Dependency injection

●   Isolated testing                             controller




                                          view                model




                                                               svc
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)
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)
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
Service Proxy
●   svc.js
                                          controller

●   Responsibilities
    ●   provide a javascript api
                                       view            model
        mapping of the server api

●   References                                          svc
    ●   the physical server via ajax
Testing the view
●   view.test.js         test

●   Inject
    ●   controllerStub
    ●   canvas                  controllerStub

●   Invoke methods
                         view
●   Assert
    ●   canvas
    ●   controllerStub
Testing the controller
●   controller.test.js                test

●   Inject
    ●   viewStub
                                    controller
    ●   modelStub

●   Invoke methods
                         viewStub                modelStub
●   Assert
    ●   viewStub
    ●   modelStub
Testing the model
●   model.test.js     test

●   Inject
    ●   serverStub
                     model
●   Invoke methods

●   Assert
                     svcStub
    ●   state
    ●   serverStub
Testing the service proxy
●   svc.test.js             test

●   Invoke methods

●   Assert
    ●   results




                            svc
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
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 jQuery's $proxy() method
    ●   Example: controller.js
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
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
Testing the backend
●   Test your webservices

●   Use QUnit and assert on the returned JSON
    ●   Or use your backend testing tool
Real World Example
●   WizerPro, in JavaScript, using MVC pattern
Further reading
●   Documentation
    ●   http://docs.jquery.com/Qunit

●   Book
    ●   "Test-Driven JavaScript Development", Christian Johansen

●   QUnit Presentation
    ●   http://benalman.com/talks/unit-testing-qunit.html
Future meetups
●   TDD coding dojo with C++ and Ruby
    ●   Thursday June 24th (in a week!)
Feedback
●   Give your evaluation at meetup.com

More Related Content

Unit Testing in JavaScript with MVC and QUnit

  • 1. Unit Testing in JavaScript with MVC and QUnit Lars Thorup ZeaLake Software Consulting June 14, 2011
  • 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. 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. JavaScript must be tested in the browser
  • 5. Example app: Collaborative Dialog ● Front end entirely in JavaScript ● Back end service methods implemented in C#
  • 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. 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. 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. Make your JavaScript testable ● MVC design pattern: Model - View - Controller ● Dependency injection ● Isolated testing controller view model svc
  • 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. 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. 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. 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. Testing the view ● view.test.js test ● Inject ● controllerStub ● canvas controllerStub ● Invoke methods view ● Assert ● canvas ● controllerStub
  • 15. Testing the controller ● controller.test.js test ● Inject ● viewStub controller ● modelStub ● Invoke methods viewStub modelStub ● Assert ● viewStub ● modelStub
  • 16. Testing the model ● model.test.js test ● Inject ● serverStub model ● Invoke methods ● Assert svcStub ● state ● serverStub
  • 17. Testing the service proxy ● svc.test.js test ● Invoke methods ● Assert ● results svc
  • 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. 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 jQuery's $proxy() method ● Example: controller.js
  • 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. 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. Testing the backend ● Test your webservices ● Use QUnit and assert on the returned JSON ● Or use your backend testing tool
  • 23. Real World Example ● WizerPro, in JavaScript, using MVC pattern
  • 24. Further reading ● Documentation ● http://docs.jquery.com/Qunit ● Book ● "Test-Driven JavaScript Development", Christian Johansen ● QUnit Presentation ● http://benalman.com/talks/unit-testing-qunit.html
  • 25. Future meetups ● TDD coding dojo with C++ and Ruby ● Thursday June 24th (in a week!)
  • 26. Feedback ● Give your evaluation at meetup.com