我在我的应用程序中有以下Angular Controller和Service设置(在Typescript中),我想为它们编写测试(使用Jasmine,Karma和PhantomJS)。
请参阅下面的错误。
有关完整源代码,请参阅:https://github.com/GarethOates/nationalrailviewer
MainController.ts
namespace app.controllers {
export class MainController implements app.Interfaces.IMainController {
public city: string;
public departures: Interfaces.IQueryResult;
public arrivals: Interfaces.IQueryResult;
public error: string;
public time: number;
public nationalRail: Interfaces.INationalRailService;
static $inject: Array<string> = ['nationalRail', '$interval', '$routeParams'];
constructor(nationalRail: app.Interfaces.INationalRailService, private $interval: ng.IIntervalService, private $routeParams: Interfaces.IParameters) {
this.nationalRail = nationalRail;
this.city = $routeParams.City;
this.GetData();
this.$interval(() => {
this.GetData();
}, 60000);
this.$interval(() => {
this.time = Date.now();
}, 1000);
}
GetData(): void {
this.nationalRail.getDepartures(this.city).then((data: app.Interfaces.IQueryResult) => {
this.departures = data;
this.error = null;
}, () => { this.error = "Unable to load data for '" + this.city + "'"; });
this.nationalRail.getArrivals(this.city).then((data: app.Interfaces.IQueryResult) => {
this.arrivals = data;
this.error = null;
}, () => { this.error = "Unable to load data for '" + this.city + "'"; });
}
}
var appModule = angular.module('nationalRailViewer')
appModule.controller('MainController', ['nationalRail', '$interval', '$routeParams',
(nationalRail: app.Interfaces.INationalRailService, $interval: ng.IIntervalService, $routeParams: Interfaces.IParameters) => new MainController(nationalRail, $interval, $routeParams)]);
}
NationalRailService.ts
namespace app.services {
export class NationalRailService implements app.Interfaces.INationalRailService {
http: ng.IHttpService;
static $inject: Array<string> = ['$http'];
constructor($http: ng.IHttpService) {
this.http = $http;
}
getDepartures(city: string): ng.IPromise<app.Interfaces.IQueryResult> {
return this.http.get("http://the.service.location.net/departures/" + city)
.then(function(response) {
return response.data;
});
}
getArrivals(city: string): ng.IPromise<app.Interfaces.IQueryResult> {
return this.http.get("http://the.service.location.net/arrivals/" + city)
.then(function(response) {
return response.data;
});
}
}
angular.module('nationalRailViewer')
.service('nationalRail', ['$http', ($http: ng.IHttpService) => new NationalRailService($http)]);
}
我想编写一个测试,确保在实例化控制器时调用getDepartures和getArrivals函数。到目前为止,我有以下规范。
controllerSpec.ts
describe("MainController Controller", function() {
var httpbackend: ng.IHttpBackendService;
var controller: app.Interfaces.IMainController;
var interval: ng.IIntervalService;
var routeParams: app.Interfaces.IParameters;
var nationalRail: app.Interfaces.INationalRailService;
var $controller: ng.IControllerService;
beforeEach(angular.mock.module("nationalRailViewer"));
beforeEach(() => angular.mock.inject(function($http: ng.IHttpService,
$httpBackend: ng.IHttpBackendService,
_nationalRail_: app.Interfaces.INationalRailService,
$controller: ng.IControllerService,
$interval: ng.IIntervalService,
$routeParams: app.Interfaces.IParameters) {
interval = $interval;
routeParams = $routeParams;
routeParams.City = "aberdeen";
httpbackend = $httpBackend;
nationalRail = _nationalRail_;
$controller = $controller;
}));
it("Should call getDepartures on NationalRailService", () => {
spyOn(nationalRail, "getDepartures").and.callFake(() => {});
controller = $controller<app.Interfaces.IMainController>('MainController', { nationalRail: nationalRail, $interval: interval, $routeParams: routeParams});
expect(httpbackend.expectGET("/departures/aberdeen")).toHaveBeenCalled();
httpbackend.flush();
});
it("Should call getArrivals on NationalRailService", () => {
spyOn(nationalRail, "getArrivals").and.callFake(() => {});
controller = $controller<app.Interfaces.IMainController>('MainController', { nationalRail: nationalRail, $interval: interval, $routeParams: routeParams});
expect(httpbackend.expectGET("arrivals/aberdeen")).toHaveBeenCalled();
httpbackend.flush();
});
});
出于某种原因,注射似乎不起作用,如果没有出现以下错误,我无法运行任何测试:
Error: spyOn could not find an object to spy upon for getArrivals()
如果我注释掉之前的测试,则以下测试会出现类似的错误。
为什么我的注入功能没有注入正确的对象?