所以我有一个像这样的功能:
function initializeView() {
var deferred = $q.defer();
var deleteOrUploadToBestMoments = this.deleteOrUploadToBestMoments;
var checkAndDeleteExpiredMoments = this.checkAndDeleteExpiredMoments;
getNearbyMoments()
.then(deleteOrUploadToBestMoments)
.then(checkAndDeleteExpiredMoments).then(function(moments) {
//omitted
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
};
我希望通过单元测试来测试此功能。这是我的测试:
it('Should call initializeView', function(done) {
spyOn(service, 'getNearbyMoments').and.callFake(function() {
console.log("MOCKED getNearbyMoments");
return $q.resolve(mockOutMoments());
});
spyOn(service, 'deleteOrUploadToBestMoments').and.callFake(function() {
console.log("MOCKED deleteOrUploadToBestMoments");
return $q.resolve();
});
spyOn(service, 'checkAndDeleteExpiredMoments').and.callFake(function() {
console.log("MOCKED checkAndDeleteExpiredMoments");
return $q.resolve();
});
service.initializeView().then(function(moments) {
//omitted
done();
});
$scope.$apply();
});
问题出在spyOn函数上。它没有嘲笑正确的功能。但是,如果我在生产代码中的getNearbyMoments前面添加一个“ this”,它将正确地模拟它:
function initializeView() {
var deferred = $q.defer();
var deleteOrUploadToBestMoments = this.deleteOrUploadToBestMoments;
var checkAndDeleteExpiredMoments = this.checkAndDeleteExpiredMoments;
this.getNearbyMoments()
.then(deleteOrUploadToBestMoments)
.then(checkAndDeleteExpiredMoments).then(function(moments) {
//omitted
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
};
我可以在生产代码中的所有函数调用之前添加一个“ this”,但是当“ this”的上下文更改时,这将成为一个问题。另外,我不必为了使测试高兴就需要更改生产代码-这使我真的很想弄清楚自己在测试中做错了什么,因此我不必为潜在的巨大问题提供帮助。
编辑:
显然我使用'this'正确地做到了。但是问题是,每当我这样做时,我都会收到一条错误消息:
'TypeError: this.getNearbyMoments is not a function`
这是我的代码:
function initializeView() {
var deferred = $q.defer();
var deleteOrUploadToBestMoments = this.deleteOrUploadToBestMoments;
var checkAndDeleteExpiredMoments = this.checkAndDeleteExpiredMoments;
var getNearbyMoments = this.getNearbyMoments;
this.getNearbyMoments()
.then(deleteOrUploadToBestMoments)
.then(checkAndDeleteExpiredMoments).then(function(moments) {
//omitted
}, function(error) {
console.log("ERROR");
console.log(error);
deferred.reject(error);
});
return deferred.promise;
};
在某些情况下,我的服务如下所示:
(function() {
angular.module('app.momentsService', [])
.service('momentsService', ['core', '$q', 'constants', 'logger', 'geolocation', 'awsServices', 'localStorageManager', momentsService]);
function momentsService(core, $q, constants, logger, geolocation, awsService, localStorageManager){
//Lots of other functions
this.checkAndDeleteExpiredMoments = checkAndDeleteExpiredMoments;
this.getNearbyMoments = getNearbyMoments;
this.deleteOrUploadToBestMoments = deleteOrUploadToBestMoments;
function getNearbyMoments() {
//Omitted...
};
function initializeView() {
//Well, you already know whats in here...
};
所以我很困惑,因为我在服务的顶部清楚地定义了功能,但是由于某种原因,它不知道它的存在。
最佳答案
spyOn(service, 'getNearbyMoments').and.callFake(function() { console.log("MOCKED getNearbyMoments"); return $q.resolve(mockOutMoments()); });
由于spyOn
的机制,因此无法修改对getNearbyMoments()
的调用。 initializeView
函数中的引用不能以这种特定方式被spyOn
覆盖。
您必须像发现的那样在this
前面添加getNearbyMoments
才能使用spyOn
。
否则,您可以通过公开公开引用getNearbyMoments
并对其进行修改来实现所需的行为。但是,基本上,您将重新实现整个模拟系统,并且执行比添加this
更复杂的事情。