【问题标题】:How to test this with Jasmine test (Behaviour Driven Development)?如何使用 Jasmine 测试(行为驱动开发)对此进行测试?
【发布时间】:2015-02-20 19:05:08
【问题描述】:

我刚刚开发了这个 JavaScript/Backbone 模块,作为我正在开发的网页的一部分。我想为它创建一个 Jasmine 测试,但我对 Jasmine 是全新的,因此我不确定我应该在这门课上测试什么。测试的“骨架”应该是什么?为了避免重复测试,你会测试哪些部分?

editdestinationview.js:

define([
    'common/jqueryex',
    'backbone',
    'marionette',
    'handlebars',
    'text!education/eet/templates/editdestination.hb',
    'text!common/templates/validationerror.hb',
    'lang/languageinclude',
    'common/i18nhelper'
], function ($, Backbone, Marionette, Handlebars, templateSource, errorTemplateSource, i18n) {
    'use strict';

    var errorTemplate = Handlebars.compile(errorTemplateSource),
        EditDestinationView = Marionette.ItemView.extend({

            initialize: function (options) {
                this._destinationTypes = options.destinationTypes;
            },

            onRender: function () {
                this.stickit();
                this._bindValidation();
            },

            _bindValidation: function () {
                Backbone.Validation.bind(this, {
                    valid: this._validAttributeCallback,
                    invalid: this._invalidAttributeCallback,
                    forceUpdate: true
                });
            },

            _validAttributeCallback: function (view, attr) {
                view.$('#error-message-' + attr).remove();
            },

            _invalidAttributeCallback: function (view, attr, error) {
                view.$('#error-message-' + attr).remove();
                view.$('#destinationTypes').parent('div').append(errorTemplate({
                    attr: attr,
                    error: error
                }));
            },

            template: Handlebars.compile(templateSource),

            ui: {
                saveAnchor: '#ed_eetSaveDestinationAnchor',
                deleteAnchor: '#ed_eetDeleteDestinationIcon'
            },

            triggers: {
                'click @ui.saveAnchor': 'click:saveDestination',
                'click @ui.deleteAnchor': 'click:deleteDestination'
            },

            bindings: {
                'select#destinationTypes': {
                    observe: 'destinationTypeId',
                    selectOptions: {
                        collection: function () {
                            return this._destinationTypes;
                        },
                        labelPath: 'description',
                        valuePath: 'destinationTypeId',
                        defaultOption: {label: i18n.EDUCATION_EET_SELECT_INTENDED_DESTINATION, value: null}
                    }
                }
            }

        });

    return EditDestinationView;
});

谢谢大家!

更新: 想了很多之后,我认为我应该尝试这些方面: -触发器:检查它们是否可以被点击。 -“_validAttributeCallback”和“_invalidAttributeCallback”:检查它们的行为是否符合代码。 -模板:监视它以检查它是否正在执行任务。 (可选测试)

因此,测试框架将是:

define([
    'education/eet/views/editdestinationview'
], function (EditDestinationView) {

    describe('description...', function () {

        beforeEach(function () {
            //EditDestinationView.triggers
        });

        describe('blablabla', function () {

            beforeEach(function () {
//                ...
            });

            it('blablabla', function () {
//      blablabla
            });

        });
    });

});

请帮忙看看如何测试?

【问题讨论】:

    标签: javascript unit-testing backbone.js jasmine bdd


    【解决方案1】:

    一种常见的模式是使用两个describe 语句,一个用于类,一个用于被测试的方法,然后一个it 语句用于您要测试的关于该方法的每件事。 rspec 人有一个约定(我在我的 JS 测试中使用),在方法 describe 上使用“#”作为实例方法,并使用“。”对于静态方法的describe

    现在,如果您采用上述所有方法,并且想要测试(例如)您的View 的点击处理方法是否触发了ViewModel 上的某个事件,它会看起来像这样:

    define([
        'education/eet/views/editdestinationview'
    ], function (EditDestinationView) {
        describe('EditDestinationView', function () {
            var view;
            beforeEach(function () {
                // do setup work that applies to all EditDestinationView tests
                view = new EditDestinationView({model: new Backbone.Model()});
            });
            describe('#handleClick', function () {
                beforeEach(function () {
                    // do setup work that applies only to handleClick tests
                });
                it('triggers a foo event', function () {
                    var wasTriggered;
                    view.model.on('foo', function() {
                        wasTriggered = true;
                    });
                    view.handleClick();
                    expect(wasTriggered).toBe(true);
                });
            });
        });
    });
    

    附:大多数人没有像我那样创建一个假的“foo”处理程序,而是使用像 Sinon 这样的模拟库。使用该库,我们的“it”语句可以改为:

                it('triggers a foo event', function () {
                    var triggerStub = sinon.stub(view.model, 'trigger');
                    view.handleClick();
                    expect(triggerStub.calledOnce).toBe(true);
                    expect(triggerStub.args[0][0]).toBe('foo');
                    //NOTE: args[0][0] == first arg of first call
                });
    

    【讨论】:

    • 首先非常感谢您的帮助,但我无法正常工作:-( 测试视图时,我应该在“定义”中“导入”模型和控制器吗?抱歉如果问题很基本,但我对 Jasmine 是全新的。
    • 在我提供的示例代码中,您可能需要的唯一内容是 Backbone(即使这样,也只有在您尚未全局定义 Backbone 变量时)。你遇到了什么错误?
    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    相关资源
    最近更新 更多