What's wrong with Angular service test?

Showing 1-7 of 7 messages
What's wrong with Angular service test? Ksenia Mukhortova 11/27/12 1:52 AM
Hi everyone,

I've got a service calling external web service:
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',
            params: {
                featureClass: "P",
                style: "full",
                maxRows: 12,
                name_startsWith: request.destName
            }
        }).success(function (data, status) {
            console.log(data);
            response($.map(innerMatch(data.geonames), matcher));
        });
    };
});

I'm trying to test that it correctly forms the output, so I mock the call to real web service. 
Here is my unit-test.
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);
        });
    });
});
But the test produces an error.
        TypeError: Cannot read property 'length' of undefined
            at Function.v.extend.map (/app/lib/jquery-1.8.3.min.js:2:15334)

I suppose it's something wrong with mock respond, as it seems it doesn't return the array.
But I can't understand why it doesn't return the array.

Thanks in advance!
Re: [AngularJS] What's wrong with Angular service test? Pete Bacon Darwin 11/27/12 2:05 AM
Don't run unit tests with minified code.  Try removing jQuery altogether and see what you get.  Also try hitting the JSONP url directly in your unit test to see what the mock actually returns.
Pete


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

Re: [AngularJS] What's wrong with Angular service test? Ksenia Mukhortova 11/27/12 2:33 AM
Oh yeah, of course :)

angular.module('myApp.services', [])
.service('autoCmpltDataSvc', function ($http) {
    var innerMatch = function (data) {
        return $.map(data, function (item) {  // line 8
            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',
            params: {
                featureClass: "P",
                style: "full",
                maxRows: 12,
                name_startsWith: request.destName
            }
        }).success(function (data, status) {
            console.log(data);
            response($.map(innerMatch(data.geonames), matcher));
        });
    };
});

Re: [AngularJS] What's wrong with Angular service test? Pete Bacon Darwin 11/27/12 2:44 AM
OK so your success function is expecting your http call to return an object with a field called geonames, currently your mock is returning a straight array.

Perhaps you should change your mock to this?

$httpBackend.whenJSONP(/searchJSON/).
              respond( { geonames: [
                { name: 'City1', adminName1: 'Region1', countryName: 'Country1', geonameId: 1 },
                { name: 'City2', countryName: 'Country2', geonameId: 2}]
              });
Re: [AngularJS] What's wrong with Angular service test? Ksenia Mukhortova 11/27/12 2:51 AM
Thank you, this did help!
I really didn't notice that the real server returned object with geonames field rather than array.

BTW, is there any way to debug the unit tests?
Re: [AngularJS] What's wrong with Angular service test? Pawel Kozlowski 11/27/12 3:00 AM
Hi!

On Tue, Nov 27, 2012 at 11:51 AM,  <ksenia.m...@gmail.com> wrote:

> BTW, is there any way to debug the unit tests?

If you are running those tests in a real browser (you are using
Testacular, right?) just add the 'debugger' statement:

debugger;

t so the execution is suspended, browser is paused so you can debug
(make sure that the developer tools / firebug or whatever else you are
using is open, otherwise execution won't stop).

Vojta also had a video showing how to debug from an IDE:
https://github.com/vojtajina/testacular

but I didn't set it up myself, always debugging in a browser.

Cheers,
Pawel
Re: [AngularJS] What's wrong with Angular service test? Ksenia Mukhortova 11/27/12 3:32 AM
Cool, thanks! It worked