【问题标题】:TypeError when testing JavaScript function with Jasmine使用 Jasmine 测试 JavaScript 函数时出现 TypeError
【发布时间】:2015-04-16 09:18:25
【问题描述】:

我是 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)

错误似乎发生在期望语句之前。当我将期望语句注释掉时,测试甚至失败了。 editProfile 函数中是否有任何对象无法实例化?还是 Jasmine 试图渲染某些东西有问题?如何从测试代码中解决这个问题? 提前致谢!

【问题讨论】:

    标签: javascript testing jasmine


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我通过添加一个全局标志解决了这个问题: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(),但也许这不是解决这个问题的最佳方法。有人知道更好的解决方案吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多