2

$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

単体テストを書くのはこれが初めてで、その後にいくつかのチュートリアルを読みました。私は何が間違っているのか分かりませんか?

4

1 に答える 1

5

あなたの問題は単純ですが、一般的なものです。

Jasmine / Karma 単体テストを作成する場合、コントローラーの作成は$controllerサービスを使用してほぼ自動的に行われます。つまり、ほとんどの場合、単体テストから言えることです

$controller('ArticleDetailCtrl')

AngularJS は、依存するサービスを見つけ出し、それらを注入して、単体テスト用のコントローラーのインスタンスを作成します。

これには 1 つの例外があります。

AngularJS は、コントローラーの各インスタンスの HTML 構造と URL に基づいて変化する $scope や $routeParams などのコンテキスト固有のサービスを挿入する方法を知りません。

単体テストで、コントローラーを次のように作成していることに気付きました

ArticleDetailCtrl = $controller('ArticleDetailCtrl', { $scope: scope });

したがって、この時点で、コントローラーが依存サービスとして $scope を要求するときに使用するオブジェクトを AngularJS に指示します。ただし、コントローラーでは、$routeParams も注入します。そして、そのarticleIdに基づいて、リクエストの URL を作成します。

したがって、コントローラーのインスタンス化コードを次のように変更すると:

ArticleDetailCtrl = $controller('ArticleDetailCtrl', { 
    $scope: scope, 
    $routeParams: articleId: ArticleId
});

これで正しい URL が作成されるはずです (エラーであった articleId に undefined を使用する代わりに)

それが役立つかどうか教えてください。

于 2014-08-21T08:03:07.993 に答える