所以我有一个像这样的功能:

        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更复杂的事情。

10-06 04:25