如何测试模板是否已经为mocha测试中的铁路由器路由呈现?

时间:2016-08-08 14:18:35

标签: javascript meteor mocha iron-router meteor-blaze

在我的meteor应用程序中,我希望能够测试是否为特定路径/路径呈现了某个模板。我目前的设置包括以下内容:iron:router,practicalmeteor:mocha,我正在使用Blaze进行渲染。

特别是有两个问题我无法开始工作:

  • 等待路线完成而不使用setTimeout(我更喜欢某种回调)
  • 确定Blaze模板是否已在页面上呈现。

如何在调用Router.go()之后测试模板是否已呈现?

import { Router } from 'meteor/iron:router';
import { Template } from 'meteor/templating';
import { chai } from 'meteor/practicalmeteor:chai';

Router.route('/example', { name: 'exampleTemp' });

describe('example route', function() {
    it('renders template exampleTemp', function() {
        Router.go('/example');
        // not sure what to put here to wait for route to finish

        // don't know how to achieve the function below
        chai.assert.isTrue(Template.exampleTemp.isRendered());
    });
});

1 个答案:

答案 0 :(得分:0)

这不是一个完美的解决方案,因为如果您定义了onAfterAction挂钩,它会覆盖onAfterAction挂钩。此外,它还将onRendered函数添加到模板中,从而创建一个混乱的测试环境

路由器helpers.test.js

import { Template } from 'meteor/templating';
import { Tracker } from 'meteor/tracker';
import { Router } from 'meteor/iron:router';

export const withRenderedRoute = function(templates, callback) {
    let routeRendered = new ReactiveVar(false);
    Router.onAfterAction(function() {
        routeRendered.set(true);
    });
    let templatesRendered = [];
    if (Array.isArray(templates)) {
        templates.forEach(function(templateName) {
            let rendered = new ReactiveVar(false);
            Template[templateName].onRendered(function() {
                rendered.set(true);
            });
            templatesRendered.push(rendered);
        });
    }
    Tracker.autorun(function() {
        const areTemplatesRendered = templatesRendered.every(function(rendered) {
            return rendered.get();
        });
        if (routeRendered.get() && areTemplatesRendered) {
            Router.onAfterAction(function() {});
            if (callback) {
                callback();
            }
        }
    });
};

router.test.html

<template name="dummyLayout">{{> yield}}</template>
<template name="dummyTemplate"></template>

router.test.js

import { chai } from 'meteor/practicalmeteor:chai';
import { withRenderedRoute } from './router-helpers.test.js';
import './router.test.html';
import './router.js';

const RoutesToTest = [
    { name: 'home', path: '/', template: 'home', layout: 'layoutDefault' }
    // more routes
];

describe('router', function() {
    before(function() {
        Router.route('/dummyRoute', { name: 'dummyRoute', template: 'dummyTemplate', layoutTemplate: 'dummyLayout' });
    });
    beforeEach(function(done) {
        Router.go('dummyRoute');
        withRenderedRoute(['dummyTemplate'], done);
    });
    after(function() {
        Router.go('/');
    });
    RoutesToTest.forEach(function(testRoute) {
        let message = 'route ' + testRoute.name + ' with path ' + testRoute.path;
        message += ' should render template ' + testRoute.template + ' with layout ' + testRoute.layout;
        it(message, function(done) {
            Router.go(testRoute.name);
            withRenderedRoute([testRoute.template, testRoute.layout], function() {
                // the route and templates have been rendered correctly at this point, otherwise the test will timeout
                chai.assert.equal(Router.routes[testRoute.name].path(), testRoute.path);
                done();
            });
        });
    });
});