Asynchronous tests

233 views
Skip to first unread message

David Foley

unread,
Nov 12, 2010, 1:36:10 PM11/12/10
to js-test...@googlegroups.com
Hi there,

loving JsTestDriver, but one question- is there any explicit support for asynchronous unit testing, and if not, is it a planned feature?
While its possible to approximate testing of asynchronous methods, I'm running into a brick wall. To give you an example:

function send ()
{
var relay= new RelayResponder
relay.result.bind(relay).defer(0);
return relay;
}

RelayResponder (this is based on an old ActionScript 1 object, by the way) allows you to add and remove responders, where a
responder is any object that implements both a result and a fault method. When you invoke the relays result method, all the responders
added to it have their result method called, or if I invoke relay.fault, all the responders will have their fault methods called.
The utility of the technique is that you can tell an object about the outcome of an operation (success or error) after the fact.
That being the case, I can invoke send like so

send().addResponder
(
{
result: function (value)
{
alert('result');
}

, fault: function (value)
{
alert('fault')
}
}
)

In the send method above I am deferring the execution of the relays result method by 0 milliseconds via an extension to Function.prototype.
The actual time elapsed before execution is actually between 7 and 15 ms, but regardless, the result of invoking send like above, is
that my responder object will have its result method called. This would not be possible without deferring execution of relay.result.

Now, putting the reasons why I am using this technique to the side, how would I use jsTestDriver to unit test the send method without
simulating it? I would imagine that an asynchronous unit test would look something like this:

TestCase
(
'com.example.SendTestCase'
, {
testSend: function ()
{
var responded= false
, responder=
{
result: function ()
{
responded= true
}
, fault: function () {}
}
, relay= send()
relay.addResponder(responder)

this.wait(15, function ()
{
assertTrue('The responders result method was called', responded);
}
}
}
)

Is there anything like this in the works or planned for the future or there already that I can use?

Thanks and apologies for the long question, just wanted to make sure I communicated the use case.

David

Robert Dionne

unread,
Nov 12, 2010, 4:07:43 PM11/12/10
to js-test...@googlegroups.com
Hello David,

You're in luck; JsTestDriver (synced to HEAD) supports asynchronous testing via http://code.google.com/p/js-test-driver/wiki/AsyncTestCase.

Please read the above documentation. If you have any questions, please direct them to me, perhaps on this thread.

-Robert






--
You received this message because you are subscribed to the Google Groups "JsTestDriver" group.
To post to this group, send email to js-test...@googlegroups.com.
To unsubscribe from this group, send email to js-test-drive...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/js-test-driver?hl=en.


Christian Johansen

unread,
Nov 12, 2010, 4:33:26 PM11/12/10
to js-test...@googlegroups.com
I also want to make a case for stubbing/mocking in this case. Running the test asynchronously is all well and good, but if you have a lot of these, your tests will slow down. I wrote Sinon.JS (http://cjohansen.no/sinon) which works very well with JsTestDriver, and using it you can do:

TestCase('com.example.SendTestCase', sinon.testCase({
    testSend: function () {
        var responder = {
            result: this.spy(),
            fault: function () {}
        }
        
        var relay = send();
        relay.addResponder(responder);

        this.clock.tick(15);

        sinon.assertCalled(responder.result);
    }
}));

In my opinion, this is better because it leaves the test more straight-forward AND it will run faster.

Best,
Christian

--
MVH
Christian
Reply all
Reply to author
Forward
0 new messages