Garrarufa
Garrarufa

Reputation: 1215

TypeError when testing JavaScript function with Jasmine

I am new to JavaScript and testing. My task is to test this function within a RequireJS Module:

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');
  },

I wrote this test with 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();
        });
    });

But the last two tests fail with these errors:

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)

The error seems to occur before the expect statement. The tests even failed when I commented the expect statements out. Is there maybe any object in the editProfile function that can't be instanciated? Or is there a problem with Jasmine trying to render something? How can I solve this from within the test code? Thanks in advance!

Upvotes: 0

Views: 670

Answers (2)

Garrarufa
Garrarufa

Reputation: 1215

I solved the problem by adding a global flag: TEST. My test functions look like this now:

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();
});

And I changed the function generateConsistentElements() that caused the problem:

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

Now I can execute editProfile() without errors, but maybe this is not the best way to solve this problem. Does anybody know a better solution?

Upvotes: 0

marcel
marcel

Reputation: 3149

Where do you declare router? Try to declare it in beforeAll function.

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

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

Upvotes: 1

Related Questions