单元测试Angular自举代码

Unit testing Angular bootstrapping code

本文关键字:代码 Angular 单元测试      更新时间:2024-06-13

更新:找到了一个我满意的解决方案,答案如下

我有一个使用手动引导的应用程序,其中有一大块代码,基本上看起来像这样:

(function() {
    'use strict';
        angular.element( document ).ready( function () {
            function fetchLabels( sLang, labelPath ) {
                // retrieves json files, builds an object and injects a constant into an angular module
            }
            function rMerge( oDestination, oSource ) {
                // recursive deep merge function
            }
            function bootstrapApplication() {
                angular.element( document ).ready( function () {
                    angular.bootstrap( document, [ 'dms.webui' ] );
                });
            }
            fetchLabels( 'en_AU' ).then( bootstrapApplication );
        }

它工作得很好——本质上是获取两个json文件,将它们组合起来,并将结果作为常量注入,然后引导应用程序。

我的问题是如何对这些函数进行单元测试?我想写一些东西来测试fetchLabels()和rMerge()方法,但我不知道该怎么做。我的第一个想法是将这些方法分离到一个服务中并以这种方式使用它,但在启动应用程序之前,我不确定我是否真的可以以这种方式调用自己的服务?

否则,有人能提出一种方法,将这些方法分离成独立的方法,让我更容易测试吗?

经过一番努力,我找到了一个我满意的解决方案。

我将这些方法移到标签服务中,并修改标签模块文件,将一个空对象预设到相关常量中。

我在我的grunt注入设置中添加了一个异常,以忽略标签服务文件,而是在前面我调用模块文件本身的地方手动调用它们。

我从引导脚本中获取了$http和$q的直接注入代码,并将它们放入Label服务中,因为在引导之前,它们不可用于正常注入。

最后,我手动加载标签模块,注入标签服务,然后使用标签服务执行上述方法。

所以我的引导脚本现在看起来是这样的:

(function () {
    'use strict';
    var injector = angular.injector( [ 'labels' ] );
    var Labels = injector.get( 'Labels' );
    /**
     * Executes the actual bootstrapping
     */
    function bootstrapApplication() {
        angular.element( document ).ready( function () {
            angular.bootstrap( document, [ 'myAppModule' ] );
        });
    }
    // get the label files and build the labels constant, then load the app
    Labels.fetchLabels( 'en_AU', '/lang/' ).then( bootstrapApplication );
})();

我可以适当地离散地对Labels服务进行单元测试。对我们来说,加载顺序和在加载模块的正常方式中添加额外的位是一个例外,但我很放心,它的特定目的保证了例外,这使我们在测试方面处于更灵活的位置。