【问题标题】:Testing a Controller using Jasmine in Karma在 Karma 中使用 Jasmine 测试控制器
【发布时间】:2013-10-03 15:12:50
【问题描述】:

我正在尝试测试控制器,但出现错误

TypeError: Object # has no method 'apply' ReferenceError: 注入未定义

unit-test.js 是

define(['angular',
        'myApp',
        'angularMocks',
        'MyCtrl'
], function() {

describe('Testing controller', function() {
        var $scope = null;
        var ctrl = null;

        beforeEach(angular.module('myApp'));

        beforeEach(inject(function ($injector) {
            $scope = $injector.get('$rootScope');
            $controller = $injector.get('$controller');
        }));


     describe('MyCtrl', function () {
        it('should call test variable', function () {
                $scope = $rootScope.$new();

                ctrl = $controller('MyCtrl', {
                    $scope: $scope
                });

                expect($scope.test).toBe("sth");
            });
        });

    });
});

在 MyCtrl 中我声明了一个 $scope.test = "sth";

当我改变时

beforeEach(angular.module('myApp'));beforeEach(module('myApp'));

我收到ReferenceError: module is not defined

我使用 Karma 版本:0.9.8 和 AngularJS v1.0.8

非常感谢!

【问题讨论】:

  • 看来你在使用 requirejs ?如果是,我可以发布一个回答并告诉你如何为 karma 实现 require.js 的配置
  • 是的,我确实使用了 requirejs,但我认为这两个文件(karma.conf.js 和 test-main.js)都是正确的。
  • 我已经在您的测试文件上发布了完整配置和修改的答案

标签: unit-testing angularjs jasmine karma-runner


【解决方案1】:

如果你使用 requirejs,你有很多事情要做。

首先你必须把karma-requirejs插件放到你的package.json

"karma-requirejs": "~0.1.0",

然后你必须改变你的配置文件。您必须在 frameworks 部分中添加 requirejs 然后排除您的要求main.js

然后通过 pattern 配置而不是 include 添加所有库文件

您必须添加您的要求main-test.js(用于测试的配置文件在底部描述)

module.exports = function (config) {
    config.set({ 
        basePath: '',

        frameworks: ['jasmine', 'requirejs'],

        files: [
            {pattern: 'app/bower_components/jquery/jquery.min.js', included: false},

            {pattern: 'app/bower_components/angular/angular.min.js', included: false},
            {pattern: 'app/bower_components/angular-resource/angular-resource.min.js', included: false},
            {pattern: 'app/bower_components/angular-mocks/angular-mocks.js', included: false},
            {pattern: 'app/scripts/*.js', included: false},
            {pattern: 'app/scripts/**/*.js', included: false},
            {pattern: 'test/spec/**/*Spec.js', included: false},
            'test/main-test.js'
        ],

        exclude: ['app/scripts/main.js'],

        port: 8082,

        logLevel: config.LOG_DEBUG,

        autoWatch: false,

        browsers: ['Chrome'],

        singleRun: false
    });
};

现在创建您的main-test.js

您必须获取所有测试文件以将其作为依赖项。

然后做一个经典的 requirejs 配置(注意在baseUrl 我们使用/base 一个业力常数),最后通过代码启动业力:window.__karma__.start();

例子:

var tests = [];
for (var file in window.__karma__.files) {
    if (window.__karma__.files.hasOwnProperty(file)) {
        if (/Spec\.js$/.test(file)) {
            tests.push(file);
        }
    }
}

require.config({

    // Karma serves files from '/base'
    baseUrl: '/base/app/scripts',

    paths: {
        jquery: '../bower_components/jquery/jquery.min',
        angular: '../bower_components/angular/angular.min',
        angularMocks: '../bower_components/angular-mocks/angular-mocks',
        ngResource: '../bower_components/angular-resource/angular-resource.min'
    },

    shim: {
        jquery: {
            exports: '$'
        },
        angular: {
            deps: [ 'jquery', 'bootstrap'],
            exports: 'angular'
        },
        ngResource: {
            deps: [ 'angular' ],
            exports: 'ngResource'
        },
        angularMocks: {
            deps: [ 'ngResource' ],
            exports: 'angularMocks'
        }
    },

    priority: [
        'angular'
    ],

    // ask Require.js to load these files (all our tests)
    deps: tests

});

require(tests, function(){
    window.__karma__.start();
});

在你的测试文件中:

beforeEach(angular.module('myApp')); 更改为beforeEach(module('myApp'));

像这样改变你定义的参数:

define(['angular',
        'myApp',
        'angularMocks',
        'MyCtrl'
], function(angular, myApp, angularMocks, MyCtrl) 

要注入控制器,只需这样做(您必须将 MyCtrl 放在您的 require 函数的参数中):

beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    $controller(MyCtrl, {
      $scope: scope
    });
  }));

最后:

it('should call crudListMethods', function () {
    expect(scope.test).toBe("sth");
});

现在应该可以了!希望对您有所帮助!

【讨论】:

  • 非常感谢 Thomas,但我仍然收到 ReferenceError: module is not defined
  • 我添加了这个,我也试过了,function('angular', 'myApp', 'angularMocks', 'MyCtrl') { 但不幸的是我仍然没有定义模块。谢谢你的努力,真的很感激。
  • 你的业力配置文件和主测试文件和我一样吗?请用我的 conf 测试一下
  • 我有错误的角度模拟文件。我接受了你的回答作为解决方案,谢谢博库托马斯。
猜你喜欢
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
相关资源
最近更新 更多