2

我是使用 Jasmine 进行 Durandal.js 和 Javascript 测试的新手,需要一些帮助。我已经设法使用 Karma 和 Jasmine 建立并运行了一个测试环境,但我很难弄清楚如何测试包含 i18next 依赖项的视图模型。

这是我的设置的精简示例:

main.js

requirejs.config({
    paths: {
        'models': 'models',
        'text': '../lib/require/text',
        'durandal': '../lib/durandal/js',
        'plugins': '../lib/durandal/js/plugins',
        'transitions': '../lib/durandal/js/transitions',
        'knockout': '../lib/knockout/knockout-2.3.0',
        'bootstrap': '../lib/bootstrap/js/bootstrap.min',
        'jquery': '../lib/jquery/jquery-1.9.1',
        'i18next': '../lib/i18next/i18next.amd.withJQuery-1.7.1.min'
    }
});

define(['plugins/router', 'durandal/system', 'durandal/app', 'durandal/binder', 'durandal/viewLocator', 'knockout', 'jquery', 'i18next'], function (router, system, app, binder, viewLocator, ko, $, i18n) {    
    app.configurePlugins({
        router: true
    });

    app.start().then(function () {
        // Setup of i18n
        i18n.init({
            detectFromHeaders: false,
            fallbackLng: 'en',
            preload: ['nb', 'en'],
            supportedLngs: ['nb', 'en'],
            resGetPath: 'locales/__lng__.json',
            useCookie: true,
        }, function () {
            binder.binding = function (obj, view) {
                $(view).i18n();
            };

            viewLocator.useConvention();
            app.setRoot('viewmodels/shell');
        });
    });
});

外壳.js

define(['plugins/router', 'durandal/app', 'i18next'], function (router, app, i18n) {
    return {
        router: router,
        activate: function () {
            return router.map([
                { route: '', title: i18n.t('pageTitle'), moduleId: 'viewmodels/ViewModel', nav: true }
            ]).buildNavigationModel().mapUnknownRoutes('viewmodels/ViewModel', 'unknown').activate({
                pushState: false,
                hashChange: true
            });
        }
    };
});

test.js(自己的 require.js 配置)

var tests = [];

for (var file in window.__karma__.files) {
    if (window.__karma__.files.hasOwnProperty(file)) {
        if (/.*\.spec\.js$/.test(file)) {
            tests.push(file);
        }
    }
}

//Workaround for the timestamp issue
for (var file in window.__karma__.files) {
    window.__karma__.files[file.replace(/^\//, '')] = window.__karma__.files[file];
}

require.config({
    baseUrl: 'base',
    paths: {
        'models': 'app/models',
        'viewModels': 'app/viewmodels',
        'specs': 'tests/specs/',
        'text': 'lib/require/text',
        'durandal': 'lib/durandal/js',
        'plugins': 'lib/durandal/js/plugins',
        'transitions': 'lib/durandal/js/transitions',
        'knockout': 'lib/knockout/knockout-2.3.0',
        'jquery': 'lib/jquery/jquery-1.9.1',
        'i18next': 'lib/i18next/i18next.amd.withJQuery-1.7.1.min',
    },

    // ask Require.js to load these files (all our tests)
    deps: tests,

    // start test run, once Require.js is done
    callback: window.__karma__.start
});

业力.conf.js

// Karma configuration

module.exports = function (config) {
    config.set({
        // base path, that will be used to resolve files and exclude
        basePath: '',


        // frameworks to use
        frameworks: ['jasmine', 'requirejs'],


        // list of files / patterns to load in the browser
        files: [
            { pattern: 'lib/jquery/jquery-1.9.1.js', watched: false, included: true, served: true },
            { pattern: 'tests/jasmine/jasmine-jquery.js', watched: false, served: true, included: true },

            { pattern: 'tests/specs/**/*.js', included: false },
            { pattern: 'tests/sinon.js', included: false },
            { pattern: 'lib/**/*.js', included: false, served: true },
            { pattern: 'app/**/*.js', included: false, served: true },

            'tests/test.js',

            //Serve the fixtures
            { pattern: 'app/**/*.html', watched: true, served: true, included: false },
            { pattern: 'app/**/*.json', watched: true, served: true, included: false },
            { pattern: 'tests/**/*.json', watched: true, served: true, included: false }
        ],

        preprocessors: [
            { '**/*.html': '' }
        ],
        // list of files to exclude
        exclude: [
            'foundation/*.js',
            'require.js',
            'init.js',
            'jasmine/jasmine.js',
            'jasmine/jasmine-html.js',
            'node_modules/**/*.html'
        ],


        // test results reporter to use
        // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
        reporters: ['progress'],


        // web server port
        port: 9876,


        // enable / disable colors in the output (reporters and logs)
        colors: true,


        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,


        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,


        // Start these browsers, currently available:
        // - Chrome
        // - ChromeCanary
        // - Firefox
        // - Opera
        // - Safari (only Mac)
        // - PhantomJS
        // - IE (only Windows)
        browsers: ['PhantomJS'],
        //browsers: ['Chrome', 'Firefox', 'IE'],

        // If browser does not capture in given timeout [ms], kill it
        captureTimeout: 60000,


        // Continuous Integration mode
        // if true, it capture browsers, run tests and exit
        singleRun: false
    });
};

视图模型(i18next):

define(["i18next"], function (i18n) {
    var pageTitle = i18n.t("pageTitle");

    return {
        pageTitle: pageTitle
    };
});

规格(i18next)

define(['viewModels/ViewModel'], function (ViewModel) {
    describe("Viewmodel test", function () {
        it("should be testable", function () {
            expect(true).toEqual(true);
        });
        it("should have title", function () {
            expect(ViewModel.pageTitle).not.toBeEmpty();
        });
    });
});

测试运行器输出

PhantomJS 1.9.2 (Mac OS X) 错误 ReferenceError: 找不到变量: 在 /Users/xxx/dev/projectXYZ/lib/i18next/i18next.amd.withJQuery-1.7.1.min.js:5 PhantomJS 1.9 初始化.2 (Mac OS X):执行 0 of 0 错误 (0.312 秒 / 0 秒)

ViewModel (wo/i18next):

define([], function () {
    var pageTitle = "This is the page title";

    return {
        pageTitle: pageTitle
    };
});

规格(wo/i18next)

define(['viewModels/ViewModel'], function (ViewModel) {
    describe("Viewmodel test", function () {
        it("should be testable", function () {
            expect(true).toEqual(true);
        });
        it("should have title", function () {
            expect(ViewModel.pageTitle).toEqual("This is the page title");
        });
    });
});

测试运行器输出(wo/i18next)

PhantomJS 1.9.2 (Mac OS X):执行 2 of 2 成功(0.312 秒 / 0.164 秒)

我想我必须以某种方式初始化 i18next,但我不知道如何。

任何帮助将非常感激。

问候,

雷米


更新

这就是我最终做的事情:

测试.js:

'i18next-original': 'lib/i18next/i18next.amd.withJQuery-1.7.1.min',
'i18next': 'tests/i18n-test'

i18n-test.js:

define(['i18next-original'], function (i18noriginal) {
'use strict';

i18noriginal.init({
    lng: 'nb',
    detectFromHeaders: false,
    fallbackLng: 'en',
    preload: ['nb', 'en'],
    supportedLngs: ['nb', 'en'],
    resGetPath: 'base/locales/__lng__.json',
    useCookie: false,
    debug: false,
    getAsync: false
});

return i18noriginal;
});

业力.conf.js:

{ pattern: 'tests/i18n-test.js', included: false, served: true },
4

1 回答 1

0

哈莱雷米!您可以像这样在 beforeEach 中初始化 i18next:

define(['viewModels/ViewModel', 'i18next'], function (ViewModel, i18n) {
    describe("Viewmodel test", function () {
        beforeEach(function() {
            var initialized = false;

            runs(function() {
                i18n.init({
                    detectFromHeaders: false,
                    fallbackLng: 'en',
                    preload: ['nb', 'en'],
                    supportedLngs: ['nb', 'en'],
                    resGetPath: 'locales/__lng__.json',
                    useCookie: true
                }, function () { initialized = true; });
            });

            waitsFor(function() {
                return initialized;
            }, 'i18n to initialize', 100);
        });

        it("should be testable", function () {
            expect(true).toEqual(true);
        });
        it("should have title", function () {
            expect(ViewModel.pageTitle).not.toBeEmpty();
        });
    });
});

为了将测试集中在 viewModel 本身的代码上,您可以考虑改为模拟 viewModel 中使用的 i18n 对象。

testr.js 可能会帮助您模拟 require.js 依赖项:https ://github.com/medallia/testr.js

于 2013-12-22T04:03:43.717 回答