4

外部 Web サービスを呼び出すサービスがあります。

angular.module('myApp.services', [])
.service('autoCmpltDataSvc', function ($http) {
    var innerMatch = function (data) {
        return $.map(data, function (item) {
            return {
                fullName: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
                shortName: item.name,
                itemId: item.geonameId
            };
        });
    };

    this.fetchFromGeonamesDb = function (request, response, matcher) {
        $http({
            method: 'jsonp',
            url: 'http://ws.geonames.org/searchJSON?callback=JSON_CALLBACK',
            params: {
                featureClass: "P",
                style: "full",
                maxRows: 12,
                name_startsWith: request.destName
            }
        }).success(function (data, status) {
            console.log(data);
            response($.map(innerMatch(data.geonames), matcher));
        });
    };
});

出力が正しく形成されることをテストしようとしているので、実際の Web サービスへの呼び出しをモックします。これが私の単体テストです。

describe('Services', function () {

    beforeEach(module('myApp.services'));

    describe('autoCompleteService', function () {
        var $httpBackend, svc;
        var results = [];
        var matcher = function (item) {
            return item;
        };
        var response = function (arr) {
            results = arr;
        };

        beforeEach(inject(function ($injector, autoCmpltDataSvc) {
            svc = autoCmpltDataSvc;
            $httpBackend = $injector.get('$httpBackend');
            $httpBackend.whenJSONP(/searchJSON/).
              respond([
              { name: 'City1', adminName1: 'Region1', countryName: 'Country1', geonameId: 1 },
              { name: 'City2', countryName: 'Country2', geonameId: 2}]);
        }));

        afterEach(function () {
            $httpBackend.verifyNoOutstandingExpectation();
            $httpBackend.verifyNoOutstandingRequest();
        });

        it('should return values', function () {
            $httpBackend.expectJSONP(/searchJSON/);
            svc.fetchFromGeonamesDb({ 'destName': 'fra' }, response, matcher);
            $httpBackend.flush();
            expect(results.length).toBe(2);
        });
    });
});

しかし、テストではエラーが発生します。

         TypeError: Cannot read property 'length' of undefined
            at Function.v.extend.map (C:/Users/kmukhort/Documents/_files/TMate/A
ngularTest/app/lib/jquery-1.8.3.min.js:2:15334)
            at innerMatch (C:/Users/kmukhort/Documents/_files/TMate/AngularTest/
app/js/services.js:8:18)

配列を返さないように見えるので、モック応答に何か問題があると思います。しかし、配列を返さない理由がわかりません。

前もって感謝します!

4

1 に答える 1

2

Peter Bacon Darwinのせいで、私のばかげた間違いが見つかりました。

OK、成功関数はhttp呼び出しがgeonamesと呼ばれるフィールドを持つオブジェクトを返すことを期待しています。現在、モックは直線配列を返しています。

おそらくあなたはあなたのモックをこれに変えるべきですか?

> $httpBackend.whenJSONP(/searchJSON/).
>               respond( { geonames: [
>                 { name: 'City1', adminName1: 'Region1', countryName: 'Country1', geonameId: 1 },
>                 { name: 'City2', countryName: 'Country2', geonameId: 2}]
>               });

https://groups.google.com/forum/#!topic/angular/u-fYR-AC8Ec

于 2012-11-27T10:55:18.020 に答える