When you compare the tests for your back-end code to the tests for your front-end code, is it like comparing Beauty to The Beast? It’s not entirely your fault; Javascript is notoriously hard to test.

There are a lot of tactics you can use to help mitigate this issue. One of the most effective that I’ve seen is to simply render the Javascript component to the DOM. That’s right, render the heck out of that component ;) . We use jstestdriver to run our Javascript tests; the tests execute in the browser, so why not make use of the awesomeness of the browser in your tests?

Let’s take the following example:

'test should show tooltip immediately if foo is true': function() {
        var cmp = Ext.create('MyComponent', {
            foo: true
        });

        cmp.render(Ext.getBody());

        Assert.isTrue(cmp.tooltip.isVisible());
}

This simple example renders cmp (an Ext Component) to the body element and asserts that it’s tooltip is visible. The reason that this test works is because the logic determining whether or not to show the tooltip immediately is in cmp’s onRender method, so we have to actually render cmp to exercise that logic.

That’s seems pretty simple, right? Well, it kinda is because of we rendered the heck out of it! :)

If we hadn’t rendered it, we probably would’ve had to write the test like this (we use sinon for stubbing):

'test should show tooltip immediately if foo is true': function() {
        var cmp = Ext.create('MyComponent', {
            foo: true,
        });
        sinon.stub(cmp, 'callParent');  //Make callParent do nothing
        sinon.stub(cmp, '_someMethodCalledByOnRenderThatDoesSomethingWithTheDom');  //Make someMethod... do nothing
        cmp.toolTip = {
            on: sinon.stub(),
            showNow: sinon.stub()
        };

        cmp.onRender();  //Directly call the onRender method

        Assert.isTrue(cmp.toolTip.showNow.calledOnce);
}

Notice how there’s a lot of stubbing out of methods (both public and private) so that methods that manipulate the DOM (onRender in the parent class and _someMethodCalledByOnRenderThatDoesSomethingWithTheDom) don’t execute. Still works but not as robust or easy to read. Rendering the component made the test a lot easier to write! :)