在通过Jasmine进行测试时,RequireJS模块垫片无法正常工作

时间:2015-08-08 21:32:31

标签: javascript maven backbone.js requirejs jasmine-maven-plugin

我有JavaEE project使用RequireJS加载一些第三方框架。其中一个框架是OpenLayers3。 Openlayers3本身创建了一个全球性的" ol"变量。但是,OpenLayers3被编写为与AMD兼容,并通过RequireJS作为模块运行。我也使用OpenLayers3 plugin名为" olLayerSwitcher"这不是针对AMD优化的。相反,它取决于" ol"变量是全球的。

我的require配置如下所示:

paths: {
    "sinon": ['/webjars/sinonjs/1.7.3/sinon'],
    "jquery": ["/webjars/jquery/2.1.4/jquery"],
    "backbone": ['/webjars/backbonejs/1.2.1/backbone'],
    "underscore": ['/webjars/underscorejs/1.8.3/underscore'],
    "text": ['/webjars/requirejs-text/2.0.14/text'],
    "log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
    "ol": ['/webjars/openlayers/3.5.0/ol'],
    "olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
    "olLayerSwitcher":  {
        deps: ["ol"],
        exports: "olLayerSwitcher"
    },
    'sinon' : {
        'exports' : 'sinon'
    }
}

该项目使用Backbone并包含一个路由器模块(/src/main/webapp/js/controller/AppRouter.js):

/*jslint browser : true*/
/*global Backbone*/
define([
    'backbone',
    'utils/logger',
    'views/MapView'
], function (Backbone, logger, MapView) {
    "use strict";
    var applicationRouter = Backbone.Router.extend({
        routes: {
            '': 'mapView'
        },
        initialize: function () {
            this.LOG = logger.init();
            this.on("route:mapView", function () {
                this.LOG.trace("Routing to map view");

                new MapView({
                    mapDivId: 'map-container'
                });
            });
        }
    });

    return applicationRouter;
});

路由器模块依赖于View模块(/src/main/webapp/js/views/MapView.js):

/*jslint browser: true */
define([
    'backbone',
    'utils/logger',
    'ol',
    'utils/mapUtils',
    'olLayerSwitcher'
], function (Backbone, logger, ol, mapUtils, olLayerSwitcher) {
    "use strict";

    [...]

    initialize: function (options) {
        this.LOG = logger.init();
        this.mapDivId = options.mapDivId;
        this.map = new ol.Map({

            [...]

                controls: ol.control.defaults().extend([
                    new ol.control.ScaleLine(),

                    new ol.control.LayerSwitcher({
                        tipLabel: 'Switch base layers'
                    })
                ])
            });

            Backbone.View.prototype.initialize.apply(this, arguments);
            this.render();
            this.LOG.debug("Map View rendered");
        }
    });

    return view;
});

View模块尝试同时提取OpenLayers3以及第三方OpenLayers插件。

构建和部署项目时,它在浏览器中工作正常。加载View模块后,OpenLayers和第三方插件就可以正常运行,所有内容都可以正常呈现。

然而,当我试图在Jasmine中测试它时,所有这一切都崩溃了。

对于Jasmine,我使用的是Jasmine-Maven插件。它将JasmineJS,PhantomJS和RequireJS与我的库一起提供并运行我的规范。问题是,当通过Jasmine运行时,MapView模块尝试加载OpenLayers3库以及第三方插件(olLayerSwitcher),但是因为第三方插件无法找到" ol"

测试:

define([
    "backbone",
    "sinon",
    'controller/AppRouter'
], function (Backbone, sinon, Router) {
    describe("Router", function () {
        beforeEach(function () {
            this.router = new Router();
            this.routeSpy = sinon.spy();
            this.router.bind("route:mapView", this.routeSpy);

            try {
                Backbone.history.start({silent: true});
            } catch (e) {
            }
            this.router.navigate("elsewhere");
        });

        it("does not fire for unknown paths", function () {
            this.router.navigate("unknown", true);
            expect(this.routeSpy.notCalled).toBeTruthy();
        });

        it("fires the default root with a blank hash", function () {
            this.router.navigate("", true);
            expect(this.routeSpy.calledOnce).toBeTruthy();
            expect(this.routeSpy.calledWith(null)).toBeTruthy();
        });   
    });
});

来自Jasmine的错误:

[ERROR - 2015-08-08T21:27:30.693Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - msg: ReferenceError: Can't find variable: ol

:262 in error
[ERROR - 2015-08-08T21:27:30.694Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - stack:
global code (http://localhost:58309/js/vendor/ol3-    layerswitcher/1.0.1/ol3-layerswitcher.js:9)

:262 in error
JavaScript Console Errors:

* ReferenceError: Can't find variable: ol

第9行的ol3-layerswitcher插件的相关部分是:

[...]
ol.control.LayerSwitcher = function(opt_options) {
[...]

所以它确实取决于" ol"在这一点上是一件事。

Jasmine-Maven插件创建了自己的规范转换器HTML,相关部分如下所示:

<script type="text/javascript">
if(window.location.href.indexOf("ManualSpecRunner.html") !== -1) {
  document.body.appendChild(document.createTextNode("Warning: Opening this HTML file directly from the file system is deprecated. You should instead try running `mvn jasmine:bdd` from the command line, and then visit `http://localhost:8234` in your browser. "))
}

var specs = ['spec/controller/AppRouterSpec.js'];

var configuration = {
  paths: {
    "sinon": ['/webjars/sinonjs/1.7.3/sinon'],
    "jquery": ["/webjars/jquery/2.1.4/jquery"],
    "backbone": ['/webjars/backbonejs/1.2.1/backbone'],
    "underscore": ['/webjars/underscorejs/1.8.3/underscore'],
    "text": ['/webjars/requirejs-text/2.0.14/text'],
    "log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
    "ol": ['/webjars/openlayers/3.5.0/ol'],
    "olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
  },
  shim: {
    "olLayerSwitcher":  {
        deps: ["ol"],
        exports: "olLayerSwitcher"
    },
    'sinon' : {
        'exports' : 'sinon'
    }
  }
};

if (!configuration.baseUrl) {
    configuration.baseUrl = 'js';
}

if (!configuration.paths) {
    configuration.paths = {};
}

if (!configuration.paths.specs) {
    var specDir = 'spec';
    if (!specDir.match(/^file/)) {
        specDir = '/'+specDir;
    }
    configuration.paths.specs = specDir;
}

require.config(configuration);

require(specs, function() {
  jasmine.boot();
});

我能够创建一个客户HTML跑步者,但我不确定问题是什么,所以我不知道需要改变什么。

这似乎不是PhantomJS问题,因为我可以在浏览器中加载测试并遇到同样的问题。

如果有人对此处可能发生的事情有任何想法,我会感激不尽。我真的不想破解第三方模块将其转换为RequireJS模块,因为Jasmine测试是完全实现这一点的最后一步,我完全陷入困境。

我正在使用Jasmine 2.3.0和RequireJS 2.1.18

我为没有链接更多而道歉,但这是一个新帐户,我没有足够的代表。

1 个答案:

答案 0 :(得分:0)

如果没有运行版本的设置,很难找出问题。 但是,如果您能够自定义maven插件生成的jasmine的SpecRunner.html,只需在SpecRunner html中包含jasmine(/导致问题的任何其他库) - <script src="/<path_to_lib>">

根据我的经验,通常不值得努力,使源库中的库使用兼容,并与其他所有库进行良好的测试设置。