Search code examples
javascriptunit-testingdojodoh

Dojo widget variable reference still held after doh test


I've been creating some tests for my Dojo widget to check that boolean flags are being set correctly. However, I've found that since I have altered my constructor to pass in an object, previously ran tests seem to affect the subsequent tests.

I've tried destroying the widget in the tear down methods, but whatever I seem to do, the value persists.

Can anyone suggest what I might be doing wrong?

My widget code:

var showControls = true;

    return declare([WidgetBase, TemplatedMixin, _WidgetsInTemplateMixin], {

        templateString: template,

        constructor: function (params) {

            this.showControls = (typeof params.showControls === "undefined" || typeof params.showControls != "boolean") ? this.showControls : params.showControls;
        }
    });

My test class is:

var customWidget;

doh.register("Test controls", [ 
    {
        name: "Test controls are not visible when set in constructor",
        runTest: function() {
            var params = { showControls: false };
            customWidget = new CustomWidget(params);
            doh.assertFalse(customWidget.getShowControls());
        }
    },
    {
        name: "Test controls are visible when set in constructor with string instead of boolean",
        runTest: function() {
            var params = { showControls: "wrong" };
            customWidget= new CustomWidget(params);
            doh.assertTrue(customWidget.getShowControls());
        }
    }
]);

So, the first test passes, as showControls is set to false, however the 2nd test attempts to create a new instance, in which the constructor will check that the value is a boolean. When I debug this however, it thinks showControls starts out as 'false', not true.

Any clues?!

Thanks


Solution

  • dijit/_WidgetBase has a mechanism of mixing in constructor parameters and it is the reason of the behavior you described. One of the possible solutions is to define a custom setter as a method _set[PropertyName]Attr:

    var defaults = {
        showControls: true
    }
    
    var CustomWidget = declare([_WidgetBase, _TemplatedMixin], {
        templateString: "<div></div>",
    
        constructor: function(params) {
            declare.safeMixin(this, defaults);
        },
    
        _setShowControlsAttr: function(value) {
            this.showControls = (typeof value === "boolean") ? value : defaults.showControls;
        }
    });
    

    See it in action: http://jsfiddle.net/phusick/wrBHp/