javascript - Have useful "Red" and "Green" tests for a View Model with throttled observables -


with of another question , relevant qunit documentation can create unit tests deal async nature of throttled knockoutjs observables.

however, haven't yet found elegant way have both red , green tests behave nicely in both test runners use:

  • the qunit browser based test runner
  • the visual studio test runner (combined chutzpah run javascript tests)

suppose following view model:

var person = function(firstname, surname) {     var self = this;      self.firstname = ko.observable(firstname);     self.surname = ko.observable(surname);      self.fullname = ko.computed({         write: function(val) {             var parts = val.split(" ");             self.firstname(parts[0]);             self.surname(parts[1]);         },         read: function() { return self.firstname() + " " + self.surname(); }     }).extend({throttle: 20}); }; 

and suppose these 2 basic tests:

test("can read full name", function(){     var john = new person("john", "doe");     strictequal(john.fullname(), "john doe"); });   test("can write full name", function(){     var person = new person();     person.fullname("john doe");     strictequal(person.firstname(), "john");     strictequal(person.surname(), "doe"); }); 

the latter will fail. makes sense, because asserts run instantly, whereas actual update fullname call runs later: delayed 20 ms throttle. without throttle things succeed.

no problem, linked question learned can use async test , use manual subscription make things green again:

asynctest("can write full name", function(){     var person = new person();      expect(2);      person.surname.subscribe(function(val) {         start();         strictequal(person.firstname(), "john");         strictequal(person.surname(), "doe");     });          person.fullname("john doe"); }); 

now, suppose break view model this:

// self.surname(parts[1]); // "bug" introduced demonstrate problem 

then test runner hang. can "fix" issue resuming test after -say- 2 seconds no matter ending test this:

// after 2 secs assume test failed settimeout(function() {     start(); }, 2000); 

this works in browser based test runner bugged code, has error on correct code, console:

pushfailure() assertion outside test context, ... @ qunit.start

makes sense, because start() called twice. first intuition check in settimeout callback see "trancount" (i.e. ask qunit if need start or not), qunit has no support (probably reason :d).

anyways, sum possible situations:

  • green because okay.
  • red because subscription never fired.
  • red because assertion failed.

how structure test situations accounted , both test runners react nicely?

found @ least 1 solution problem while writing question. posting question along answer (a) in case may others and/or (b) other folks may have better solutions this.

bottom line clear settimeout return value subscription fires:

asynctest("can write full name", function(){     var person = new person();      // after 2 secs assume test failed     var timeout = settimeout(function() {         start();     }, 2000);      expect(2);      person.surname.subscribe(function(val) {         window.cleartimeout(timeout);         start();         strictequal(person.firstname(), "john");         strictequal(person.surname(), "doe");     });      person.fullname("john doe"); }); 

this works scenarios:

both red cases have nice assertion failure.

only downside solution it's bit verbose, need 4 lines of testing-plumbing. (perhaps else has answer utilizing feature of qunit purpose?)

also, 1 other downside: if increase throttle above timeout test first goes red qunit will crash bit later because start() called once more.


Comments

Popular posts from this blog

java - WrongTypeOfReturnValue exception thrown when unit testing using mockito -

php - Magento - Deleted Base url key -

android - How to disable Button if EditText is empty ? -