Testing a Controller using Jasmine in Karma

时光毁灭记忆、已成空白 提交于 2019-12-06 11:10:43

问题


I'm trying to test a controller but I'm getting an error

TypeError: Object # has no method 'apply' ReferenceError: inject is not defined

The unit-test.js is

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");
            });
        });

    });
});

in MyCtrl I have declared a $scope.test = "sth";

When I change

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

I'm getting ReferenceError: module is not defined

I use Karma version: 0.9.8 and AngularJS v1.0.8

Thank you very much!


回答1:


You have a lot of things to do if you're using requirejs.

First you have to put the karma-requirejs plugin in your package.json

"karma-requirejs": "~0.1.0",

Then you have ti change your config file. You have to add requirejs in frameworks part Then exclude your require main.js

Then add all your librairies files via the pattern config and not include it

You have to add your require main-test.js (config file for test describe at bottom)

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
    });
};

Now create your main-test.js.

In you have to get all your tests files to put it as dependencies.

Then do a classic requirejs config (note in the baseUrl we use /base a karma constant) and finally start karma by code through : window.__karma__.start();

Example :

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();
});

In your test file :

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

Change the params of your define like that :

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

To inject controller just do that (You have to put the MyCtrl in param of your require function) :

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

And finally :

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

Now it should work ! Hope it helps !



来源:https://stackoverflow.com/questions/19162809/testing-a-controller-using-jasmine-in-karma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!