gpt4 book ai didi

angularjs - 使用服务对 Controller 进行 Angular 单元测试 - 注入(inject)时中断

转载 作者:行者123 更新时间:2023-12-02 08:34:59 24 4
gpt4 key购买 nike

我正在为 karma 编写单元测试,但无法运行它。它似乎破坏了注入(inject)功能。我认为这与我在测试中如何获取 Controller 有关,但找不到解决方案。

我最近几天刚刚开始使用 Angular,所以任何建议将不胜感激,谢谢!

错误:

Error: Argument 'fn' is not a function, got string
at Error (<anonymous>)
at $a (path/app/lib/angular.js:16:453)
at qa (path/app/lib/angular.js:17:56)
at Cb (path/app/lib/angular.js:24:458)
at Object.d [as invoke] (path/app/lib/angular.js:27:66)
at path/app/lib/angular.js:26:194
at Array.forEach (native)
at m (path/app/lib/angular.js:6:192)
at e (path/app/lib/angular.js:25:298)
at Object.sb [as injector] (path/app/lib/angular.js:29:360)
TypeError: Cannot read property 'zip' of undefined
at null.<anonymous> (path/test/unit/controllersSpec.js:26:19)

测试:

'use strict';

/* jasmine specs for controllers go here */

describe('influences controllers', function() {
beforeEach(module('influences.controllers', ['ui.bootstrap', 'influences.services']));

describe('IndividualCtrl', function(){

var scope, ctrl, service, $httpBackend;

beforeEach(inject(function(_$httpBackend_, $rootScope, $controller, Api_sunlight_get) {
console.log('*** IN INJECT!!***: ', Api_sunlight_get);
$httpBackend = _$httpBackend_;
// ignore for now... this is an example of how I might implement this later
// $httpBackend.expectGET('data/products.json').
// respond([{name: 'Celeri'}, {name: 'Panais'}]);

scope = $rootScope.$new();
service = Api_sunlight_get;
ctrl = $controller('IndividualCtrl', {$scope: scope, Api_sunlight_get: service
});
}));

it('should create "products" model with 2 products fetched from xhr', function() {
console.log('*** IN TEST!!***: ', scope);
expect(scope.zip).toEqual(12345);
});
});
});

Controller :

angular
.module('influences.controllers', ['ui.bootstrap', 'influences.services'])
.controller('IndividualCtrl', ['$scope', 'Api_sunlight_get', ($scope, Api_sunlight_get)->
# set default variables
$scope.zip = $scope.zip or 94102 # set default zip if one is not chosen

# Define Methods
$scope.get_rep_data_by_zip = ()->
$scope.reps = Api_sunlight_get "legislators/locate?zip=#{$scope.zip}" $scope.update_rep_data_by_zip

$scope.update_rep_data_by_zip = ()->
$scope.selected_rep = $scope.reps # sets default selection for reps buttons
for rep in $scope.reps
rep.fullname = "" + rep.title + " " + rep.first_name + " " + rep.last_name

# watchers
$scope.$watch('zip', $scope.get_rep_data_by_zip)

# initial run
$scope.get_rep_data_by_zip()

服务:

angular
.module('influences.services', [])
.factory 'Api_sunlight_get', ['$http', ($http)->
return (path, callback)->
$http
url: "http://congress.api.sunlightfoundation.com/#{path}&apikey=xxxx"
method: "GET"
.success (data, status, headers, config)->
callback data.results
.error (data, status, headers, config)->
console.log("Error pulling #{path} from Sunlight API!")
]

最佳答案

我认为这是模块influences.controllers的依赖项未加载的问题。我尝试了你的程序的一个相当缩小的版本,并得到了与你完全相同的错误。咨询了this question后才知道。在这里我设法得到它。请阅读作者的答案,我认为这会很有帮助。

无论如何,这就是您应该执行的操作来加载 中的 actual ui.bootstrapinfluences.services 模块测试文件:

'use strict';

/* jasmine specs for controllers go here */

describe('influences controllers', function() {
// Change is here. Notice how the dependencies of the influences.controllers
// module are specified separately in another beforeEach directive
beforeEach(module('influences.controllers'));
beforeEach(function() {
module('ui.bootstrap');
module('influences.services');
});

describe('IndividualCtrl', function(){

var scope, ctrl, service, $httpBackend;

beforeEach(inject(function(_$httpBackend_, $rootScope, $controller, Api_sunlight_get) {
console.log('*** IN INJECT!!***: ', Api_sunlight_get);
$httpBackend = _$httpBackend_;
// ignore for now... this is an example of how I might implement this later
// $httpBackend.expectGET('data/products.json').
// respond([{name: 'Celeri'}, {name: 'Panais'}]);

scope = $rootScope.$new();
service = Api_sunlight_get;
ctrl = $controller('IndividualCtrl', {$scope: scope, Api_sunlight_get: service
});
}));

it('should create "products" model with 2 products fetched from xhr', function() {
console.log('*** IN TEST!!***: ', scope);
expect(scope.zip).toEqual(12345);
});
});
});

如果您想模拟这两个依赖项,您可能需要查阅上面的链接,为了方便起见,我将在此处重复该链接:Mocking Angular module dependencies in Jasmine unit tests

下面是我尝试过的缩小版本的所有文件,如果您有兴趣的话。只需将它们放在同一个文件夹中即可。您将需要 karmaangular.jsphantomjsangular-mocks 来运行测试。 Angular-Mocks 可以从 Angular-Seed 项目 here 获得.

要运行测试,只需:

karma start karma.test.conf.js

很抱歉将所有文件放在这里,因为我真的不知道像这样放置多个文件的好地方。

ctrl.js:

angular.module('influences.controllers', ['influences.services'])
.controller('IndividualCtrl', [
'$scope',
'Api_sunlight_get',
function($scope, Api_sunlight_get) {
$scope.zip = $scope.zip || 12345;
}
])

service.js:

angular.module('influences.services', [])
.factory('Api_sunlight_get', [
'$http',
function($http) {
console.log('Api_sunlight_get factory called');
}
])

test.spec.js:

describe('influences controllers', function() {
beforeEach(module('influences.controllers'));
beforeEach(function() {
module('influences.services');
});
describe('IndividualCtrl', function() {
var scope
, ctrl
, service
, $httpBackend;
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller, Api_sunlight_get) {
console.log('*** IN INJECT!! ***');
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
service = Api_sunlight_get;
ctrl = $controller('IndividualCtrl', {
$scope: scope,
Api_sunlight_get: service
});
}));

it('should set the correct zip value', function() {
expect(scope.zip).toBe(12345);
});
});
});

karma.test.conf.js:

// Karma configuration
// Generated on Tue Jul 02 2013 11:23:33 GMT+0800 (SGT)


// base path, that will be used to resolve files and exclude
basePath = './';


// list of files / patterns to load in the browser
files = [
JASMINE,
JASMINE_ADAPTER,
'angular.min.js',
'angular-mocks.js',
'service.js',
'ctrl.js',
'test.spec.js'
];


// list of files to exclude
exclude = [
];


// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters = ['progress'];

hostname = '127.0.0.1';

// web server port
port = 9876;


// cli runner port
runnerPort = 9100;


// enable / disable colors in the output (reporters and logs)
colors = true;


// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_INFO;


// enable / disable watching file and executing tests whenever any file changes
autoWatch = true;


// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers = ['PhantomJS'];


// If browser does not capture in given timeout [ms], kill it
captureTimeout = 60000;


// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = true;

关于angularjs - 使用服务对 Controller 进行 Angular 单元测试 - 注入(inject)时中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17902003/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com