2013-04-23 78 views
4

我對Angular和Jasmine非常陌生,當我試圖僞造服務「查詢」調用時遇到問題。由「描述」包圍下:Angular Jasmine SpyOn查詢電話

var mockBackend; 

beforeEach(inject(function($rootScope, $controller, AppServ) { 
    // We need to setup our controllers to use fake services provided by angular-mocks 
    $scope = $rootScope.$new(); 
    mockBackend = AppServ; 

    $controller('AppInformationController', { 
    $scope: $scope, 
    AppServ: mockBackend 
    }); 
})); 

it("should try to call the service, but we intercept it", function() { 
    spyOn(mockBackend, 'query').andReturn({'title':'Mock title'}); 

    $scope.serverAppNameChange(); 
    expect($scope.app.title).toBe("Mock title"); 
}); 

以上「的appserv」是我的服務,我想,攔截於該服務的測試呼叫「查詢」返回一些默認信息。真的,這只是爲了瞭解Jasmine和Angular的工作原理。服務本身沒有做任何事情,只能保留本地副本(這基本上是假的服務)。

這裏的服務:

Services.factory("AppServ", function($http) { 
    var app = {}; 
    var theAppOnServer = {}; 

    app['query'] = function() { 
    return theAppOnServer; 
    }; 

    app['save'] = function(app) { 
    theAppOnServer = $.extend({}, app); 
    }; 

    app['updateApp'] = function() { 
    theAppOnServer['title'] = "Title From Server"; 
    }; 

    return app; 
}); 

這裏是控制器:

MobileIntake.controller("AppInformationController", function($scope, AppServ) { 
    $scope.app = AppServ.query(); 

    //var AppOverviewController = function($scope) { 
    $scope.appNameChange = function(oldValue, newValue, scope) { 
    console.log("You've changed the app name!"); 
    }; 

    $scope.serverAppNameChange = function() { 
    AppServ.updateApp(); 
    }; 
    // Set up a watcher if we want to be updated by other things (like the server) 
    $scope.$watch("app.title", $scope.appNameChange); 

}); 

可能有人請我的線索,爲什麼spyOn似乎並沒有被攔截的「查詢」函數調用服務?我已經看到了其他一些答案,他們使用$ http和一些特殊的邏輯,但我只是想讓我可以攔截非http函數。

回答

4

您不需要額外的mockBackend對象。只是監視服務本身。

beforeEach(inject(function($rootScope, $controller) { 
    // We need to setup our controllers to use fake services provided by angular-mocks 
    $scope = $rootScope.$new(); 

    $controller('AppInformationController', { 
    $scope: $scope 
    }); 
})); 

it("should try to call the service, but we intercept it", inject(function(AppServ) { 
    spyOn(AppServ, 'query').andReturn({'title':'Mock title'}); 

    $scope.serverAppNameChange(); 
    expect($scope.app.title).toBe("Mock title"); 
})); 
+0

我得到「AppServ」未定義。我的「AppInformationController」需要注入AppServ,並得到那我不需要仍然在「注入(函數($ rootScope,$控制器,AppServ))」部分? – Chris 2013-04-23 20:52:53

+0

你從哪裏獲得AppServ未定義?你添加了'inject'到你的'它'吧?爲您的測試設置控制器時,您不需要爲'$ controller'服務提供所有的依賴關係。在angular的phonecat應用程序(https://github.com/angular/angular-phonecat)中,他們有一個控制器,可以注入一個「Phone」資源(https://github.com/angular/angular-phonecat/blob/master/ app/js/controllers.js),但在測試中(https://github.com/angular/angular-phonecat/blob/master/test/unit/controllersSpec.js#L18),它們不會傳遞給它'$ controller'。 – dnc253 2013-04-24 14:45:58

+0

在PhoneCat示例中,測試使用'ctrl = $ controller(PhoneListCtrl,{$ scope:scope});'您可以看到「PhoneListCtrl」是全局範圍內的一個變量,不像。例子是。我有更好的經驗使用全局變量而不是module.controller類型符號來進行測試,但它應該能夠以任何一種方式進行測試。 – Chris 2013-04-24 20:39:44