Top Banner
Unit Testing in JavaScript with MVC and QUnit Lars Thorup ZeaLake Software Consulting June 14, 2011
26

Unit Testing in JavaScript with MVC and QUnit

May 07, 2015

Download

Technology

Lars Thorup

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 http://www.zealake.com/public/javascript-unit-testing.zip
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Unit Testing in JavaScript with MVC and QUnit

Unit Testing in JavaScript with MVC and QUnitLars ThorupZeaLake Software Consulting

June 14, 2011

Page 2: Unit Testing in JavaScript with MVC and QUnit

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

Page 3: Unit Testing in JavaScript with MVC and QUnit

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

Page 4: Unit Testing in JavaScript with MVC and QUnit

JavaScript must be tested in the browser

Page 5: Unit Testing in JavaScript with MVC and QUnit

Example app: Collaborative Dialog● Front end entirely in JavaScript

● Back end service methods implemented in C#

Page 6: Unit Testing in JavaScript with MVC and QUnit

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)

Page 7: Unit Testing in JavaScript with MVC and QUnit

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

Page 8: Unit Testing in JavaScript with MVC and QUnit

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

Page 9: Unit Testing in JavaScript with MVC and QUnit

Make your JavaScript testable

● MVC design pattern: Model - View - Controller

● Dependency injection

● Isolated testing controller

view model

svc

Page 10: Unit Testing in JavaScript with MVC and QUnit

View● view.js

● injected html● load html page from the server● html becomes directly stylable

● Responsibilities● manipulate html● generate html from templates● dispatch events to listeners● nothing more!

● References● a set of event listeners

(typically the controller)

controller

view model

svc

Page 11: Unit Testing in JavaScript with MVC and QUnit

Controller● controller.js

● Responsibilities● handle all events from the

view● poll model for change events if

relevant● convert events to commands

against the model● repaint strategy● error handling strategy

● References● the model (to execute

commands, polling)● the view (to do repainting)

controller

view model

svc

Page 12: Unit Testing in JavaScript with MVC and QUnit

Model● model.js

● Responsibilities● cache state to minimize round

trips● provide view and controller

with a useful interface of the data model

● References● the service proxy

controller

view model

svc

Page 13: Unit Testing in JavaScript with MVC and QUnit

Service Proxy● svc.js

● Responsibilities● provide a javascript api

mapping of the server api

● References● the physical server via ajax

controller

view model

svc

Page 14: Unit Testing in JavaScript with MVC and QUnit

Testing the view● view.test.js

● Inject● controllerStub● canvas

● Invoke methods

● Assert● canvas● controllerStub

controllerStub

view

test

Page 15: Unit Testing in JavaScript with MVC and QUnit

Testing the controller● controller.test.js

● Inject● viewStub● modelStub

● Invoke methods

● Assert● viewStub● modelStub

controller

viewStub modelStub

test

Page 16: Unit Testing in JavaScript with MVC and QUnit

Testing the model● model.test.js

● Inject● serverStub

● Invoke methods

● Assert● state● serverStub

model

svcStub

test

Page 17: Unit Testing in JavaScript with MVC and QUnit

Testing the service proxy● svc.test.js

● Invoke methods

● Assert● results

svc

test

Page 18: Unit Testing in JavaScript with MVC and QUnit

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

Page 19: Unit Testing in JavaScript with MVC and QUnit

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

Page 20: Unit Testing in JavaScript with MVC and QUnit

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

Page 21: Unit Testing in JavaScript with MVC and QUnit

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

Page 22: Unit Testing in JavaScript with MVC and QUnit

Testing the backend● Test your webservices

● Use QUnit and assert on the returned JSON● Or use your backend testing tool

Page 23: Unit Testing in JavaScript with MVC and QUnit

Real World Example● WizerPro, in JavaScript, using MVC pattern

Page 24: Unit Testing in JavaScript with MVC and QUnit

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

Page 25: Unit Testing in JavaScript with MVC and QUnit

Future meetups● TDD coding dojo with C++ and Ruby

● Thursday June 24th (in a week!)

Page 26: Unit Testing in JavaScript with MVC and QUnit

Feedback● Give your evaluation at meetup.com