设置webpack业力和角度模拟

时间:2017-03-30 07:00:42

标签: webpack karma-runner angular-mock

我在设置webpack时遇到此问题。我正在现有项目上设置webpack,另外我正在介绍ES6。我想以“正确”的方式做这件事,经过一些重大改变后测试通过。这就是我需要设置业力测试的原因。 该应用程序使用的是AngularJS 1,对于测试,我使用的是Angular-Mocks(使用Jasmina和PhantomJS设置karma)。

我去了很多现有的解决方案如何使用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

我正在运行Angular 1.6.2,Webpack 2.2.1,Karma-Webpack 2.0.2和版本1.5.0的Karma。 我正在尝试在ES6中编写我的模块并在webpack中进行转换。 你们可以帮忙吗?我现在已经坚持了很长时间; /我知道有更新的“更好”的解决方案来测试ES6模块,但我需要

你们能帮助我吗?

1 个答案:

答案 0 :(得分:0)

有时,当AngularJS无法找到所需的提供程序时,此设置可能会非常麻烦。它不会抛出错误,而是退出,不输入任何var groups = transactions.GroupBy(t=>t, new TransactionDebCredComparer() ); 函数并启动inject块。因此,您通常从it获得的值仍未定义。

看看您是否通过$injector包含它们的模块,还是通过创建和配置间谍对象来模拟所有必需的依赖。

angular.mock.module('serviceModule')