设置 webpack karma 和 angular-mocks

Setting up webpack karma and angular-mocks

我在设置我的 webpack 时遇到了这个问题。我正在现有项目上设置 webpack,另外我正在引入 ES6。我想以 'correct' 的方式进行测试,在一些大的 change.That 之后通过测试,这就是我需要设置业力测试的原因。 该应用程序正在使用 AngularJS 1,并且我正在使用 Angular-Mocks(使用 Jasmina 和 PhantomJS 进行业力设置)进行测试。

我抛出了很多现有的解决方案,如何使用 karama 和 angular 设置 webpack,但是没有一个例子让我的测试工作。基本上问题在于注入和模拟。 例如,我在尝试注入 $rootScope 或 $backendMock 时变得不确定。

这是我当前的设置:

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const rootPath = path.resolve(__dirname, "src");
const libsDir = rootPath + "/lib";
const applicationDir = libsDir + "/app";

const plugins =
    [
        new CleanWebpackPlugin('build', {
            root: rootPath,
            verbose: true,
            dry: false
        }),
        new webpack.EnvironmentPlugin({
            PROD_ENV: false
        }),
        new HtmlWebpackPlugin({
            template: 'src/index.tmpl.ejs',
            inject: 'head',
            filename: 'index.html'
        }),
        new ExtractTextPlugin('style/[name].css'),
        new webpack.ProvidePlugin({
            $: "jquery",
            jquery: "jquery",
            "window.jQuery": "jquery",
            jQuery: "jquery"
        })
    ];


module.exports = {
    devtool: 'source-map',
    entry: {
        vendors: libsDir + "/components.js",
        application: applicationDir + "/Application.js",
        browserDetect: applicationDir + "/BrowserDetection.js"
    },
    output: {
        path: __dirname + "/build",
        publicPath: '',
        filename: "[name].bundle.js",
        sourceMapFilename: "[name].bundle.map",
        chunkFilename: '[chunkhash].js'
    },
    module: {
        loaders: [
            {
                test: /\.html$/,
                loader: "ngtemplate-loader!html-loader"
            }, {
                test: /\.(svg|png|jpe?g|ttf|woff2?|eot)$/,
                loader: 'url-loader?limit=10000&name=style/[name].[ext]'
            }, {
                test: /\.(scss|css)$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    //resolve-url-loader may be chained before sass-loader if necessary
                    use: ['css-loader?minimize', 'resolve-url-loader', 'sass-loader?sourceMap']
                })
            }
        ]
    },
    plugins: plugins,
    node: {
        net: 'empty',
        tls: 'empty',
        //dns: 'empty',
        fs: 'empty'
    }
};

karma.config.js

var webpackConfig = require('./webpack.config');

module.exports = function (config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['jasmine'],

        // list of files / patterns to load in the browser
        files: [
            'node_modules/angular/angular.js',
            'node_modules/angular-mocks/angular-mocks.js',
            {pattern: 'tests/karma.entry.js'}
        ],

        // list of files to exclude
        exclude: [],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            'tests/karma.entry.js' : ['webpack']
        },

        webpack: webpackConfig,

        webpackMiddleware: {
            stats: "errors-only"
        },

        ngHtml2JsPreprocessor: {
            // setting this option will create only a single module that contains templates
            // from all the files, so you can load them all with module('foo')
            moduleName: 'templates',
            stripPrefix: 'src/'
        },

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter

        //TEST
        // reporters: ['progress', 'html', 'junit', 'coverage'],

        //TEST
        // coverageReporter: {
        //     dir: 'reports',
        //     reporters: [
        //         {type: 'cobertura', subdir: 'xml', file: 'code-coverage.xml'},
        //         {type: 'html', subdir: 'html'}
        //     ]
        // },

        // the default configuration
        htmlReporter: {
            outputFile: 'reports/html/ui-unit-tests.html'
        },

        junitReporter: {
            outputFile: 'reports/xml/ui-unit-tests.xml'
        },

        // 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_DEBUG,

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

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['PhantomJS'],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true ,

        plugins: [
            require('karma-webpack'),
            require('karma-jasmine'),
            require('karma-coverage'),
            require('karma-phantomjs-launcher'),
            require('karma-chrome-launcher'),
        ].
    });
};

karma.entry.js

var testsContext = require.context(".", true, /\.spec\.js/);
testsContext.keys().forEach(testsContext);

没有我所有的测试都在一个单独的文件中 -> /tests/**/*.spec.js,这些被拾取并且 PhanthomJS 正在尝试 运行 它们。

这是我的一项测试运行:

describe('contextmenu', function () {
    var customersEndpoint = '/api/v1/res/customers',
        directiveScope,
        $httpBackendMock,
        contextMenuDomElement,
        compileDirective,
        contextService,
        contextsReturnedFromBackend = [
            {name: "Kjell's Buildings and Stuffz", id: 1},
            {name: "IMA Stats Runners", id: 2},
            {name: "Juice and Gin Inc.", id: 3}
        ];

    beforeEach(angular.mock.module("FES"));
    beforeEach(angular.mock.module("templates"));


    beforeEach(function () {
        angular.mock.inject(function (_$rootScope_, _$compile_, _$httpBackend_, _ContextService_) {
            contextService = _ContextService_;
            $httpBackendMock = _$httpBackend_;

            $httpBackendMock.when('GET', customersEndpoint)
                .respond(contextsReturnedFromBackend);

            compileDirective = function() {
                directiveScope = _$rootScope_.$new();
                contextMenuDomElement = _$compile_(angular.element("<contextmenu></contextmenu>"))(directiveScope);
                directiveScope.$digest();
            };
        });
    });

    describe('on init', function() {
       it('calls the context service to get available contexts and select first item', function() {
           $httpBackendMock.expectGET(customersEndpoint);
           compileDirective();
           $httpBackendMock.flush(); // this returns the $http request that was made on init in the controller
            directiveScope.$digest();
           console.log(directiveScope);
           expect(directiveScope.contexts.length).toBe(3);
           expect(contextMenuDomElement.html()).toContain(contextsReturnedFromBackend[0].name);
       })
    });

    describe('on context clicked', function() {
        it('sets the current context', function() {
            var newContextToSelect = directiveScope.contexts[1];
            directiveScope.onContextClicked(newContextToSelect);
            expect(directiveScope.selectedContext).toBe(newContextToSelect);
        });
    });
});

我收到的错误是 $httpBackendMock 或 directiveScope 未定义。

PhantomJS 2.1.1 (Linux 0.0.0) contextmenu on init calls the context service to get available contexts and select first item FAILED
        forEach@node_modules/angular/angular.js:402:24
        loadModules@node_modules/angular/angular.js:4880:12
        createInjector@node_modules/angular/angular.js:4802:30
        WorkFn@node_modules/angular-mocks/angular-mocks.js:3161:60
        inject@node_modules/angular-mocks/angular-mocks.js:3141:46
        tests/karma.entry.js:165:28
        loaded@http://localhost:9876/context.js:151:17
        node_modules/angular/angular.js:4921:53
        TypeError: undefined is not an object (evaluating '$httpBackendMock.expectGET') in tests/karma.entry.js (line 182)
        tests/karma.entry.js:182:28
        loaded@http://localhost:9876/context.js:151:17
PhantomJS 2.1.1 (Linux 0.0.0) contextmenu on context clicked sets the current context FAILED
        forEach@node_modules/angular/angular.js:402:24
        loadModules@node_modules/angular/angular.js:4880:12
        createInjector@node_modules/angular/angular.js:4802:30
        WorkFn@node_modules/angular-mocks/angular-mocks.js:3161:60
        inject@node_modules/angular-mocks/angular-mocks.js:3141:46
        tests/karma.entry.js:165:28
        loaded@http://localhost:9876/context.js:151:17
        node_modules/angular/angular.js:4921:53
        TypeError: undefined is not an object (evaluating 'directiveScope.contexts') in tests/karma.entry.js (line 194)
        tests/karma.entry.js:194:52
        loaded@http://localhost:9876/context.js:151:17

我正在 运行ning Angular 1.6.2、Webpack 2.2.1、Karma-Webpack 2.0.2 和 1.5.0 版的 Karma。 我试图在 ES6 中编写我的模块并在 webpack 中转换它。 你们能帮忙吗?我已经坚持了很长时间;/我知道有新的 'better' 解决方案来测试 ES6 模块,但我需要

你们能帮帮我吗?

当 AngularJS 找不到所需的提供商时,此设置有时会非常糟糕。它没有抛出错误,而是退出,不输入任何 inject 函数并启动 it 块。因此,您通常从 $injector 中获得的值仍然未定义。

看看您是否真的模拟了所有必需的依赖项,通过 angular.mock.module('serviceModule') 包含它们的模块,或者通过创建和配置间谍对象。

angular.mock.module(($provider: ng.auto.IProvideService) => {
  $provider.value('service', jasmine.createSpyObj('service', ['list of accessed modules']);
});