toEqualData 匹配器中断 AngularJS 应用中的测试
toEqualData matcher breaks tests in AngularJS app
我为 AngularJS 应用程序的服务编写了以下非常简单的测试:
describe('Services', function () {
beforeEach(function(){
this.addMatchers({
toEqualData: function(expected) {
return angular.equals(this.actual, expected);
}
});
});
beforeEach(module('myapp.services'));
describe('Album service', function(){
var Album;
beforeEach(inject(function (_Album_) {
Album = _Album_;
}));
it('can get an instance of the Album factory', inject(function (Album) {
expect(Album).toBeDefined();
}));
});
});
我刚刚添加了自定义 toEqualData 匹配器 as advised in the AngularJS documentation。但是,这打破了测试。我正在使用 Gulp 到 运行 与 gulp-karma
的测试(尽管如果我直接使用 Karma 也会出现同样的问题),我看到以下错误消息:
$ gulp test
[10:00:04] Using gulpfile ~/Projects/myapp/gulpfile.js
[10:00:04] Starting 'jshint'...
[10:00:04] Starting 'karma'...
WARN `start` method is deprecated since 0.13. It will be removed in 0.14. Please use
server = new Server(config, [done])
server.start()
instead.
31 07 2015 10:00:04.362:INFO [karma]: Karma v0.13.3 server started at http://localhost:9876/
31 07 2015 10:00:04.368:INFO [launcher]: Starting browser PhantomJS
[10:00:04] Finished 'jshint' after 277 ms
31 07 2015 10:00:04.631:INFO [PhantomJS 1.9.8 (Linux 0.0.0)]: Connected on socket sFxRfQ6bJtqM_utNAAAA with id 27252937
PhantomJS 1.9.8 (Linux 0.0.0) Services Album service can get an instance of the Album factory FAILED
TypeError: 'undefined' is not a function (evaluating 'this.addMatchers')
at /home/matthew/Projects/myapp/tests/services.tests.js:7
PhantomJS 1.9.8 (Linux 0.0.0): Executed 7 of 7 (1 FAILED) (0.04 secs / 0.022 secs)
[10:00:04] Finished 'karma' after 558 ms
[10:00:04] Starting 'test'...
[10:00:04] Finished 'test' after 11 μs
我看不出哪里出错了。有任何想法吗?如果我取出自定义匹配器,它实际上工作正常,我实际上还没有使用,但计划这样做。所以看起来匹配器是罪魁祸首,但由于它是从 Angular 文档中逐字复制和粘贴的,所以我不知道为什么它不起作用。
我相信您正试图在测试中注入 Album
,但这是一个实例。您已经在 beforeEach
.
中注入了 _Album_
尝试删除第二个 inject
(it()
中的那个)。
angulardocs中的例子:
// Defined out reference variable outside
var myService;
// Wrap the parameter in underscores
beforeEach( inject( function(_myService_){
myService = _myService_;
}));
// Use myService in a series of tests.
it('makes use of myService', function() {
myService.doStuff();
});
最终解决了问题。事实证明 Jasmine API 在 1.3 和 2.0 之间发生了变化,AngularJS 文档似乎没有提供任何相关信息。以下是我解决问题的方法,希望遇到此问题的任何其他人都能找到可行的解决方案:
describe('Services', function () {
beforeEach(function(){
jasmine.addMatchers({
toEqualData: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
return {
pass: angular.equals(actual, expected)
};
}
};
}
});
});
beforeEach(module('myapp.services'));
describe('Album service', function(){
var Album;
beforeEach(inject(function (_Album_, _$httpBackend_) {
Album = _Album_;
mockBackend = _$httpBackend_;
}));
it('can get an instance of the Album factory', inject(function (Album) {
mockBackend.expectGET('https://myapp.com/api/albums').respond([{id: 1}, {id: 2}]);
expect(Album).toBeDefined();
var albums = Album.query();
mockBackend.flush();
expect(albums).toEqualData([{id: 1}, {id: 2}]);
}));
});
});
基本上,您所做的就是在添加匹配器时将 this
更改为 jasmine
,将 actual
和 expected
作为参数传递给函数,然后使用他们而不是 this
。现在似乎按预期工作。
编辑:事实证明这没有用,它只是默默地失败了。我现在更正了。
我为 AngularJS 应用程序的服务编写了以下非常简单的测试:
describe('Services', function () {
beforeEach(function(){
this.addMatchers({
toEqualData: function(expected) {
return angular.equals(this.actual, expected);
}
});
});
beforeEach(module('myapp.services'));
describe('Album service', function(){
var Album;
beforeEach(inject(function (_Album_) {
Album = _Album_;
}));
it('can get an instance of the Album factory', inject(function (Album) {
expect(Album).toBeDefined();
}));
});
});
我刚刚添加了自定义 toEqualData 匹配器 as advised in the AngularJS documentation。但是,这打破了测试。我正在使用 Gulp 到 运行 与 gulp-karma
的测试(尽管如果我直接使用 Karma 也会出现同样的问题),我看到以下错误消息:
$ gulp test
[10:00:04] Using gulpfile ~/Projects/myapp/gulpfile.js
[10:00:04] Starting 'jshint'...
[10:00:04] Starting 'karma'...
WARN `start` method is deprecated since 0.13. It will be removed in 0.14. Please use
server = new Server(config, [done])
server.start()
instead.
31 07 2015 10:00:04.362:INFO [karma]: Karma v0.13.3 server started at http://localhost:9876/
31 07 2015 10:00:04.368:INFO [launcher]: Starting browser PhantomJS
[10:00:04] Finished 'jshint' after 277 ms
31 07 2015 10:00:04.631:INFO [PhantomJS 1.9.8 (Linux 0.0.0)]: Connected on socket sFxRfQ6bJtqM_utNAAAA with id 27252937
PhantomJS 1.9.8 (Linux 0.0.0) Services Album service can get an instance of the Album factory FAILED
TypeError: 'undefined' is not a function (evaluating 'this.addMatchers')
at /home/matthew/Projects/myapp/tests/services.tests.js:7
PhantomJS 1.9.8 (Linux 0.0.0): Executed 7 of 7 (1 FAILED) (0.04 secs / 0.022 secs)
[10:00:04] Finished 'karma' after 558 ms
[10:00:04] Starting 'test'...
[10:00:04] Finished 'test' after 11 μs
我看不出哪里出错了。有任何想法吗?如果我取出自定义匹配器,它实际上工作正常,我实际上还没有使用,但计划这样做。所以看起来匹配器是罪魁祸首,但由于它是从 Angular 文档中逐字复制和粘贴的,所以我不知道为什么它不起作用。
我相信您正试图在测试中注入 Album
,但这是一个实例。您已经在 beforeEach
.
_Album_
尝试删除第二个 inject
(it()
中的那个)。
angulardocs中的例子:
// Defined out reference variable outside
var myService;
// Wrap the parameter in underscores
beforeEach( inject( function(_myService_){
myService = _myService_;
}));
// Use myService in a series of tests.
it('makes use of myService', function() {
myService.doStuff();
});
最终解决了问题。事实证明 Jasmine API 在 1.3 和 2.0 之间发生了变化,AngularJS 文档似乎没有提供任何相关信息。以下是我解决问题的方法,希望遇到此问题的任何其他人都能找到可行的解决方案:
describe('Services', function () {
beforeEach(function(){
jasmine.addMatchers({
toEqualData: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
return {
pass: angular.equals(actual, expected)
};
}
};
}
});
});
beforeEach(module('myapp.services'));
describe('Album service', function(){
var Album;
beforeEach(inject(function (_Album_, _$httpBackend_) {
Album = _Album_;
mockBackend = _$httpBackend_;
}));
it('can get an instance of the Album factory', inject(function (Album) {
mockBackend.expectGET('https://myapp.com/api/albums').respond([{id: 1}, {id: 2}]);
expect(Album).toBeDefined();
var albums = Album.query();
mockBackend.flush();
expect(albums).toEqualData([{id: 1}, {id: 2}]);
}));
});
});
基本上,您所做的就是在添加匹配器时将 this
更改为 jasmine
,将 actual
和 expected
作为参数传递给函数,然后使用他们而不是 this
。现在似乎按预期工作。
编辑:事实证明这没有用,它只是默默地失败了。我现在更正了。