简体   繁体   中英

Accessing a Meteor Template Helper Function in Jasmine for Integration Testing

I'm trying to run Jasmine client integration tests on a meteor project. I'm using meteor 0.9.4 , and the sanjo:jasmine package for Jasmine.

I have written a test which looks like:

describe("Template.dashboard.tasks", function() {

    it("ela displays correct assessment", function() {
        Session.set("selected_subject", "math");
        Session.set('selected_grade', "1");

        tasks = Template.dashboard.tasks();
        expect(true).toBe(true);
    });
});

I get an error before it can get to the end of the test:

Cannot read property 'tasks' of undefined

This means that Template.dashboard does not exist within the scope of this test.

Template.dashboard.tasks() is a helper function which works completely, and it is in a js file within a view folder. Regular Jasmine tests work as expected, but as soon as I try to use one of my own functions from another file, it doesn't work.

My question is: Is there something I need to do to give the Jasmine test access to my template helper functions?

In Meteor, Template helper functions used to be formatted like this:

Template.dashboard.tasks = function () {
    ...
};

But that has been deprecated, and the new format is:

Template.dashboard.helpers({
    tasks: function(){
        ...
    }
});

In Jasmine, with the previous formatting, you could access helper functions like:

Template.dashboard.tasks();

But now you must call helper functions like this:

Template.dashboard.__helpers[' tasks']();

Sanjo (the original author of the meteor-jasmine repo ) suggested using a function like this to make it easier to call helper functions (especially if the syntax ends up getting changed again):

function callHelper(template, helperName, context = {}, args = []) {
    template.__helpers[` ${helperName}`].apply(context, args);
}

An updated answer to this question for Meteor 1.3 (sorry I use mocha, but it does not affect the answer):

Template.foo and Template.foo helpers won't be eagerly set up when testing, so you need to import foo.html then foo.js .

Here is an example :

import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { Foo } from '/collections/foo.js';
import { assert } from 'meteor/practicalmeteor:chai';
import './foo.html';  // now Template.foo is defined
import './foo.js';    // now Template.foo.__helpers[' bar'] is defined


describe('foo handlers', () => {
    it("Should test bar", () => {
       // don't forget the space, helper key is ' bar' not 'bar'
       var bar = Template.foo.__helpers[' bar'].apply({foo:"bar"},3); 
       assert.Equal(bar,'bar');
    });
});

Of course as said before, you should definitely encapsulate the weird Template.foo.__helpers[' bar'].apply(context,args) into a nice, clean helper.

tests on server part are running nicely from start, and there is indeed one more thing to do in order to run tests on the frontend part. I'll try to find you that.

In addition, consider reading or reading again the famous and explicit article from Dr. Llama's Blog related to Jasmin/Meteor : Bullet-proof Meteor applications with Velocity, Unit Testing, Integration Testing and Jasmine

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