Search code examples
javascriptjquerybackbone.jsqunit

Backbone.View test output differs console output


I don't understand the operations of Backbone.View.render() and .el. In render() I assign this.el the properties supporting the outpout I expect to see, these properties are in this.el when tested, and .el returns the expected output in console. But the output doesn't appear in testing.

Here is the code and test (please to overlook cruftiness, I am learning and struggling to keep the tests green):

var RowLabelData = Backbone.Model.extend({});

var RowLabel = Backbone.View.extend({
    initialize: function() {
           this.for_attr = this.model.get("for_attr");
           this.text_val = this.model.get("text_val");
           this.el.setAttribute("for", this.for_attr);
        },

    render: function() {
        $(this.el).html(this.text_val);
        return this;
        }
});

I test as follows with QUnit:

test_row_data   =   new RowLabelData({
                        for_attr: "id_username",
                        text_val: "Username:"
                    });
test_row_v      =   new RowLabel({
                        model: test_row_data,
                        tagName: 'label'
                    });
test_row_v.render();
test_row = test_row_v.el;

equal(test_row.textContent, "Username:");
equal(test_row.getAttribute("for"), "id_username");
// FAILS:
equal(test_row, '<label for="id_username">Username:</label>');

QUnit says that in the last test << test_row >> returns <label></label>. BUT in the JavaScript console, << test_row >> returns the string expected in the text.

The backbone docs say that render() should put the desired HTML into el, but I'm trying to use the default behavior of render(), and it does work in console. Why doesn't it work in test?


Solution

  • dira is right, the problem is comparison of an Object to a string.

    This test code creates a similar element, then converts that and the test object to strings for comparison:

    new_label = document.createElement("label");
    new_label.setAttribute("for", "id_username");
    t = document.createTextNode("Username:");
    new_label.appendChild(t);
    
    equal(
        $('<div>').append($(test_row).clone()).remove().html(),
        $('<div>').append($(new_label).clone()).remove().html(),
        "convoluted!"
    );
    

    This passes. The console output of those cthulhu-worthy incantations is "<label for="id_username">Username:</label>".

    Though it approaches those things man is not meant to know, the brave, or foolhardy, can discover this arcane secret here.