简体   繁体   中英

How to write the following test in Jasmine

My test claims to interpolate data into strings, but actually also checks if the model automatically updates the DOM. How should I handle this situation?

Test for ItemView using Jasmine:

describe("ItemView handles rendering views with a model", function() {

    it("should render a template and interpolate data from a model", function() {

        var user = new Backbone.Model({
            name    : "Peeter",
            age     : 24
        });

        var itemView = new ItemView({
            model       : user,
            template    : 'Hello my name is <%= model.get("name") %> and I\'m <%= model.get("age") %> years old.'
        });

        itemView.render();

        user.set({
            name    : "Pjotr",
            age     : 25
        });

        expect(itemView.$el).toHaveText('Hello my name is Pjotr and I\'m 25 years old.');

    });



});

* The code being tested (BaseView has his own tests) *

My base view:

define(['jquery', 'backbone', 'underscore'], function($, Backbone, _) {
    'use strict';

    var BaseView = Backbone.View.extend({

        /**
         * Update the dom element
         */
        replaceDomElement : function() {

            this.trigger("before:replace_dom_element");

            var $el = this.$el.empty();
            var $clone = $el.clone();
            $el.replaceWith($clone);
            this.setElement($clone);

            this.trigger("after:replace_dom_element");


        },
        /**
         * Default serialize function
         * @returns empty object
         */
        serialize: function(){
            return {};
        },

        /**
         * Render the view, passing the pictures collection to the view and the
         * inner template
         */
        render : function() {

            this.replaceDomElement();

            this.trigger("before:render");

            var template = _.template(this.options.template);
            /**
             * Allow for serialization overwriting
             */
            var options = this.serialize();
            if(this.options.serialize) {
                options = _.isFunction(this.options.serialize) ? this.options.serialize() : this.options.serialize;
            }

            this.$el.append(template(options));
            this.trigger("after:render");

        }

    });

    return BaseView;

});

My item view:

define(['jquery', 'yolojs/views/BaseView'], function($, BaseView) {
    'use strict';

    var ItemView = BaseView.extend({

        className : "item",

        /**
         * Helper function to determine which data should the view pass to the template
         */
        serialize : function() {
            return  {
                model : this.model
            };
        },
        /**
         * Set up our view to autoupdate on change
         */
        initialize: function() {
            /**
             * Assign the cid as a data attribute on the model 
             */
            this.$el.attr("data-cid", this.model.cid);
            this.model.on('change',this.render,this);
        }

    });

    return ItemView;

});

The simplest way to do so was:

describe("ItemView", function() {

            var user;
            var itemView;

            beforeEach(function() {

                user = new Backbone.Model({
                    name    : "Peeter",
                    age     : 24
                });

                itemView = new ItemView({
                    model       : user,
                    template    : 'Hello my name is <%= model.get("name") %> and I\'m <%= model.get("age") %> years old.'
                });

            });

            it("should render a template and interpolate data from a model", function() {

                itemView.render();

                expect(itemView.$el).toHaveText('Hello my name is Peeter and I\'m 24 years old.');

            });

            it("should call render if the models data changes", function() {

                spyOn(itemView, 'render');

                user.set({
                    name    : "Pjotr",
                    age     : 25
                });

                expect(itemView.render).toHaveBeenCalled();

            });

            it("should update the dom element with the new models data", function() {

                user.set({
                    name    : "Pjotr",
                    age     : 25
                });

                expect(itemView.$el).toHaveText('Hello my name is Pjotr and I\'m 25 years old.');

            });


        });

I also had to change my itemview a bit due to the following: Testing backbone.js application with jasmine - how to test model bindings on a view?

This answer is credited to @theml

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM