【问题标题】:Angular 1.* unable to access controller in karma unit test (webpack)Angular 1.* 无法在业力单元测试(webpack)中访问控制器
【发布时间】:2017-01-19 21:21:01
【问题描述】:

我正在尝试在 karma 中设置单元测试来测试角度 1.* 控制器。每次我运行我得到的代码时

[ng:areq] Argument 'MoviesListCtrl' is not a function, got undefined

当我检查了控制器的模块后,控制器似乎已加载,所以我不确定它为什么没有加载。我的项目可以在这里找到..

我的项目在

的 bitbucket 上可用

https://bitbucket.org/LAD500/movies-angular-webpack/src

运行测试..

npm install
npm test

对此的任何帮助将不胜感激。

我正在处理的文件是..

测试 - https://bitbucket.org/LAD500/movies-angular-webpack/src/b007e3bced7f3f6249a1b577dc83aa348490d608/test/public/js/app/services/movieslisting.spec.js

import '../../../../../src/js/app/services/movieslisting/';
import '../../../../../src/js/app/directives/movieslist/movieslistctrl';
import '../../../../../src/js/app/browserapp.js';

import {expect} from 'chai';

let createCtrl, scope, moviesListing;

beforeEach(angular.mock.module('BrowserApp'));

beforeEach(inject(($rootScope, $controller)=>{
    moviesListing = angular.injector(['ng', 'BrowserApp']).get("moviesListing");
    scope = $rootScope.$new();
    createCtrl = ()=>{
        return $controller('MoviesListCtrl', {
            $scope: scope,
            moviesListing: moviesListing
        });
    };
}));

describe('MoviesListCtrl', ()=>{

    it('placeholder test', ()=>{
        let ctrl = createCtrl();
        expect(1).to.equal(1);
    });
});

控制器

import app from '../../browserapp';

let controllerName = 'MoviesListCtrl';

app.controller('MoviesListCtrl', ['$scope', 'moviesListing', function($scope, moviesListing) {

    $scope.moviesList = {
        moviesFilter: 'costLowToHigh',
        movies: moviesListing.movieCollection
    };

    $scope.createMovieHeader = movie =>{
        let prefix = `${movie.title} (${movie.category}`;
        return movie.subcategory ? `${prefix}/${movie.subcategory})` : `${prefix})`;
    };

    $scope.updateFilter = ()=>{
        moviesListing.sortMovies($scope.moviesList.moviesFilter);
    };
    
}]);

export default controllerName;

服务是一个依赖项

import app from '../../browserapp';

let factoryName = 'moviesListing';

app.factory(factoryName, [function() {
    let movieCollection = [];

    let currentSortKey = 'costLowToHigh';

    let costLowToHigh = (a, b)=>{
        if (a.castListTotalCost > b.castListTotalCost) {
            return 1;
        }
        if (a.castListTotalCost < b.castListTotalCost) {
            return -1;
        }
        return 0;
    };
    let costHighToLow = (a, b)=>{
        if (a.castListTotalCost < b.castListTotalCost) {
            return 1;
        }
        if (a.castListTotalCost > b.castListTotalCost) {
            return -1;
        }
        return 0;
    };

    let sortFunctionsLookup = {
        costLowToHigh,
        costHighToLow
    };

    let castListTotalCost = movie => movie.actors.reduce((total, actor) => total +  actor.salary, 0);

    let addMovie = (movie)=>{
        movie.castListTotalCost = castListTotalCost(movie);
        movieCollection.push(movie);
        movieCollection.sort(sortFunctionsLookup[currentSortKey]);
    };

    let sortMovies = (sortKey)=>{
        currentSortKey = sortKey;
        movieCollection.sort(sortFunctionsLookup[currentSortKey]);
    };

    let reset = ()=>{
        movieCollection.length = 0;
    };

    return {
        movieCollection,
        addMovie,
        sortMovies,
        reset
    };
}]);

export default factoryName;

应用模块

import * as angular from 'angular';

var app = angular.module('BrowserApp', []);

app.init = ()=>{
    angular.element(document).ready(function() {
        angular.bootstrap(document, ['BrowserApp']);
    });
};

export default app;

业力配置

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

    basePath: '',

    frameworks: ['mocha', 'es6-shim'],

    files: [
      './node_modules/angular/angular.js',
      './node_modules/angular-mocks/angular-mocks.js',
      'test/**/*spec.js'
    ],

    preprocessors: {
      'test/**/*spec.js': ['webpack', 'sourcemap']
    },

    reporters: ['progress'],

    port: 9876,

    colors: true,

    logLevel: config.LOG_INFO,

    autoWatch: false,

    browsers: ['PhantomJS'],

    singleRun: true,

    concurrency: Infinity,

    webpack: {
      devtool: 'inline-source-map',
      module: {
        loaders: [
          {test: /\.js$/, exclude: /node_modules/, loader:"babel-loader"},
          { test: /\.html$/, loader: "html" }
        ]
      },
      htmlLoader: {
        attrs: false
      }
    },

    webpackMiddleware: {
      noInfo: true
    }

  })
}

【问题讨论】:

    标签: angularjs unit-testing webpack karma-runner angular-controller


    【解决方案1】:

    设法自己解决了这个问题。

    诀窍是使用 javascript 文件为您的测试生成包

    javascript 文件 specs.karma.js 看起来像这样..

    import 'angular';
    import 'angular-mocks/angular-mocks';
    
    const testsContext = require.context('./', true, /.spec$/);
    testsContext.keys().forEach(testsContext);

    Karma 配置..

    module.exports = function karmaConfig (config) {
      config.set({
        logLevel: config.LOG_INFO,
    
        client: { captureConsole: true },
    
        frameworks: ['mocha', 'es6-shim'],
    
        reporters: ['progress'],
    
        files: ['./src/js/specs.karma.js'],
    
        preprocessors: {
          './src/js/specs.karma.js': ['webpack', 'sourcemap']
        },
    
        browsers: [ 'PhantomJS'],
    
        singleRun: true,
    
        webpack: require('./webpack.test.config'),
    
        webpackMiddleware: {
          noInfo: 'errors-only'
        }
      });
    };

    还有 webpack.test.config.js..

    module.exports = {
      devtool: 'inline-source-map',
      module: {
        loaders: [
          {test: /\.js$/, exclude: /node_modules/, loader:"babel"},
          { test: /\.html$/, loader: "html" }
        ]
      },
      htmlLoader: {
        attrs: false
      }
    }

    【讨论】:

      猜你喜欢
      • 2017-01-31
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 2014-05-24
      相关资源
      最近更新 更多