我正在努力让我的第一个 Angular单元测试工作。我对很多概念都很陌生,但是由于我已经不得不跳过很多障碍才能实现这一目标,所以我发布的是代码。我见过类似的问题,但没有一个帮助我解决这个问题。
这是一个控制器:
.controller('ThumbsCtrl',
['$scope', 'backend', function($scope, backend) {
backend.getImages()
.then(function(images) {
console.log("promise.then() called with "+images);
$scope.images = images;
}, function(err) {
console.log(err);
});
}]
)
这是一个测试:
describe('ThumbsCtrl', function() {
var controller, rootScope;
beforeEach(module('myApp.controllers'));
beforeEach(inject(function($controller, $rootScope) {
controller = $controller;
rootScope = $rootScope;
}));
it('should contain images', inject(function($q) {
var scope = rootScope.$new();
var backend = {
getImages: function() {
console.log("calling mock getImages()");
var deferred = $q.defer();
deferred.resolve('shite');
return deferred.promise;
}
};
var ctrl = controller('ThumbsCtrl', {
$scope: scope,
backend: backend
});
expect(scope.images).toContain('shite');
}));
});
测试失败,因为$ scope.images从未设置过。
抛开关于让我的控制器的构造函数调用异步方法(实际的backend.getImages()也返回一个承诺)的完整性的评论,任何人都可以告诉我为什么.then()调用中的成功或失败方法都没有被称为?我的理解是通过像我一样调用deferred.resolve(),单元测试确实应该没有异步代码。但显然我错了......对吗?
答案 0 :(得分:4)
嗯,我通过添加:
来实现它scope.$digest();
在最终期望之前()。我会把这一点归结为仍然被$ q deferreds感到困惑。我来自使用Parse.com JS SDK,当它们已经调用resolve()时,它的Promises是同步的。我猜$ q deferreds仍然保持异步,即使解决了上述问题?
作为旁注,Angular支持并且很好地记录如何进行单元测试的断言并不是那么真实。我正在交叉引用AngularJS文档,一本优秀的书籍(使用AngularJS掌握Web开发),以及两者的示例代码,我发现在阅读所有这些来源一周后相当突出,我在编写简单的单元测试时遇到了麻烦。要学习的概念数量很大,我之前也没有使用过Jasmine(使用过QUnit)。我试图推迟使用Karma,所以我可以一步一步,但是jeez - 如果我不关心单元测试,我现在就跳过它来编写我的愚蠢应用程序。
答案 1 :(得分:2)
如果它有助于我遇到与您相同的问题。我现在有了一个标准,我按照所有的承诺要求放置。
afterEach(function() {
scope.$digest();
mockBackend.flush();
mockBackend.verifyNoOutstandingExpectation();
mockBackend.verifyNoOutstandingRequest();
});
这确保没有未完成的$ http请求,并且所有内容都已经过正确测试。
我同意让很多这些单元测试运行起来非常麻烦,特别是测试指令。