我正在尝试为控制器编写单元测试,该控制器使用$ http服务获取文章详细信息。
控制器:
.controller('ArticleDetailCtrl',function($scope, Article, $routeParams, API_URL, ARTICLE_URL, $http, $sce){
$scope.url = API_URL + ARTICLE_URL + '/' + $routeParams.articleId;
$http.get($scope.url).then(function(response) {
//console.log(response.data);
$scope.heading = response.data.Headline;
$scope.rawBody = response.data.Body;
$scope.body = $sce.trustAsHtml($scope.rawBody);
$scope.image = response.data.Assets[0].URL;
});
});
单元测试:
'use strict';
describe('Controller: Article', function () {
var scope,
$httpBackend,
articleEndpoint;
// load the controller's module
beforeEach(module('myApp'));
describe('ArticleDetailCtrl', function () {
var ArticleDetailCtrl,
jsonObject,
ArticleId = '123';
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope, _$httpBackend_, Article, API_URL, ARTICLE_URL) {
scope = $rootScope.$new();
ArticleDetailCtrl = $controller('ArticleDetailCtrl', { $scope: scope });
$httpBackend = _$httpBackend_;
articleEndpoint = API_URL + ARTICLE_URL + '/' + ArticleId;
jsonObject = {
'Headline': 'Headline',
'Body': '<p>Body</p>',
'Assets': [
{
'URL': 'path/to/image/article1.jpg'
}
]
};
$httpBackend.when('GET', articleEndpoint).respond(jsonObject);
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should fetch article details from the API', function () {
//expect(scope.articles.length).toEqual(3);
$httpBackend.expectGET(articleEndpoint);
$httpBackend.flush();
});
});
});
但我继续收到以下错误:
Error: Unexpected request: GET http://localhost:3000/api/articles/undefined
Expected GET http://localhost:3000/api/articles/123
at $httpBackend (/Users/gill/Documents/projects/angularjs-test/app/bower_components/angular-mocks/angular-mocks.js:1179)
at sendReq (/Users/gill/Documents/projects/angularjs-test/app/bower_components/angular/angular.js:8181)
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular/angular.js:7921
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular/angular.js:11319
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular/angular.js:11405
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular/angular.js:12412
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular/angular.js:12224
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular-mocks/angular-mocks.js:1438
at /Users/gill/Documents/projects/angularjs-test/test/spec/controllers/article.js:77
Error: Unsatisfied requests: GET http://localhost:3000/api/articles/123
at /Users/gill/Documents/projects/angularjs-test/app/bower_components/angular-mocks/angular-mocks.js:1472
at /Users/gill/Documents/projects/angularjs-test/test/spec/controllers/article.js:65
这是我第一次编写单元测试,然后我阅读了一些教程。我不知道我做错了什么?
答案 0 :(得分:5)
你的问题很简单,但很常见。
当您编写Jasmine / Karma单元测试时,使用 $ controller 服务创建控制器几乎是自动的。这意味着,在大多数情况下,您可以从单元测试中说出
$controller('ArticleDetailCtrl')
AngularJS将找出其依赖服务,注入它们并为您创建一个控制器实例进行单元测试。
有一个例外:
AngularJS不知道如何注入特定于上下文的服务,如$ scope和$ routeParams,这些服务会根据HTML结构和控制器的每个实例的URL进行更改。
我注意到在您的单元测试中,您将控制器创建为
ArticleDetailCtrl = $controller('ArticleDetailCtrl', { $scope: scope });
所以在这一点上,当告诉控制器要求$ scope作为依赖服务时,告诉AngularJS使用什么对象。但是在你的控制器中,你还注入了$ routeParams。并根据 articleId 为您创建请求的网址。
因此,如果您将控制器实例化代码更改为:
ArticleDetailCtrl = $controller('ArticleDetailCtrl', {
$scope: scope,
$routeParams: articleId: ArticleId
});
现在应该创建正确的URL(而不是使用articleId的undefined,这是错误)
如果有帮助,请告诉我。