使用Jasmine测试JavaScript函数时的TypeError

时间:2015-04-16 09:18:25

标签: javascript testing jasmine

我是JavaScript和测试新手。我的任务是在RequireJS模块中测试这个功能:

editProfile: function () {
    this.checkForReload();

    var editProfileView = new EditProfileView();
    this.changeView(editProfileView);

    //needs to be called separately since whe it's passed as parameter view to change is replaced with sidebarView
    editProfileView.generateConsistentElements(this.sidebarView, 'sidebar');

    //footer
    editProfileView.generateConsistentElements(this.footerView, 'footer');
  },

我用Jasmine编写了这个测试:

describe("function editProfile", function(){
        it ("exists", function(){
            expect(router.editProfile).toBeDefined();
        });

        it ("checks for reload", function(){
            spyOn(router, "checkForReload");
            router.editProfile();
            expect(router.checkForReload).toHaveBeenCalled();
        });

        it ("changes view", function(){
            spyOn(router, "changeView");
            router.editProfile();
            expect(router.changeView).toHaveBeenCalled();
        });
    });

但是最后两次测试失败了这些错误:

TypeError: Cannot read property 'id' of null
at BaseView.extend.render (http://localhost:63342/website/public/js/app/views/EditProfileView.js:36:41)
at setView (http://localhost:63342/website/public/js/app/routers/DesktopRouter.js:143:39)
at BaseRouter.extend.changeView (http://localhost:63342/website/public/js/app/routers/DesktopRouter.js:149:13)
at BaseRouter.extend.editProfile (http://localhost:63342/website/public/js/app/routers/DesktopRouter.js:409:14)
at Object.<anonymous> (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/spec/DesktopRouterSpec.js:82:24)
at attemptSync (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:1741:24)
at QueueRunner.run (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:1729:9)
at QueueRunner.execute (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:1714:10)
at Spec.Env.queueRunnerFactory (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:608:35)
at Spec.execute (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:346:10)

TypeError: Cannot read property 'roles' of null
at eval [as template] (eval at template (http://localhost:63342/website/public/js/libs/lodash/dist/lodash.js:6305:22), <anonymous>:8:30)
at BaseView.extend.render (http://localhost:63342/website/public/js/app/views/SidebarView.js:29:28)
at Backbone.View.extend.generateConsistentElements (http://localhost:63342/website/public/js/app/core/BaseView.js:417:46)
at BaseRouter.extend.editProfile (http://localhost:63342/website/public/js/app/routers/DesktopRouter.js:412:25)
at Object.<anonymous> (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/spec/DesktopRouterSpec.js:88:24)
at attemptSync (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:1741:24)
at QueueRunner.run (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:1729:9)
at QueueRunner.execute (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:1714:10)
at Spec.Env.queueRunnerFactory (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:608:35)
at Spec.execute (http://localhost:63342/website/jasmine_test/jasmine-standalone-2.2.0_1/lib/jasmine-2.2.0/jasmine.js:346:10)

错误似乎发生在expect语句之前。当我评论期望陈述时,测试甚至失败了。 editProfile函数中是否有任何对象无法实现?或者Jasmine试图渲染某些东西有问题吗?如何在测试代码中解决这个问题? 提前谢谢!

2 个答案:

答案 0 :(得分:1)

你在哪里声明router?尝试在beforeAll函数中声明它。

describe(...
    beforeAll(function() {
        // declare router
    });

    // .... it ....
    // .... it ....
    // .... it ....
);

答案 1 :(得分:0)

我通过添加全局标志解决了这个问题:TEST。 我的测试函数现在看起来像这样:

it ("checks for reload", function(){
    spyOn(router, "checkForReload");
    TEST = true;
    router.editProfile();
    TEST = false;
    expect(router.checkForReload).toHaveBeenCalled();
});

it ("changes view", function(){
    spyOn(router, "changeView");
    TEST = true;
    router.editProfile();
    TEST = false;
    expect(router.changeView).toHaveBeenCalled();
});

我更改了导致问题的函数generateConsistentElements():

generateConsistentElements: function (...) {
    if(!TEST){
        // code
    }
},

现在我可以无错误地执行editProfile(),但这可能不是解决此问题的最佳方法。有人知道更好的解决方案吗?