2017-01-05 2 views
0

Ich teste gerade einen eckigen Service mit Karma/Jasmin und eine meiner Service-Funktionen ist wie folgt. Ich brauche Deckung zu 100% zu erhalten, aber kann nicht scheinen, um herauszufinden, wie die beiden Erfolge und Fehlerfälle zu testen ..Wie Karma test Restangular HTTP-Aufruf mit httpbackend Test sowohl Erfolg und Fehler Fälle?

function getAccount(accountId) { 
    var defer = $q.defer(), myService; 
    myService = Restangular.all('Some/Url/Path'); 
    myService.get('', {}, { 
    'header-info': 'bla' 
    }) 
    .then(function onSuccess(response) { 
     defer.resolve(response); 
    }, function onError() { 
     someMethodCall(); 
    }); 
    return defer.promise; 
} 

In meiner .spec Testdatei entsprechen, die ich habe:

it('should succeed in getting account', function() { 
    httpBackend.whenGET('Some/Url/Path').respond(200, mockResponse); 
    var promise = myServices.getAccount('account123'); 
    promise.then(function(response) { 
    expect(response).toEqual(mockResponse); 
}); 

it('should error out in getting account', function() { 
    httpBackend.whenGET('Some/Url/Path').respond(500, ''); 
    var promise = myServices.getAccount('account123'); 
    promise.then(function() { 
    expect(someMethodCall).toHaveBeenCalled(); 
}); 

Gerade jetzt, beide Fälle "bestanden", aber ich bekomme nicht die Zweigabdeckung für den onError-Fall. Etwas scheint fischig zu sein, wenn der onSuccess-Fall auch passiert.

Im Grunde frage ich, was die richtige Syntax und Weise die Testfälle zu schreiben, so dass ich beide Erfolg treffen kann und auf Fehlerfällen, wenn ich eine 200 und eine 500 Aufruf an meine API

Antwort

1

Da Sie don machen Ich habe keine Anrufe an $http in Ihrem Service, ich würde empfehlen, Restangular statt httpBackend zu verspotten. Auf diese Weise muss Ihr Test nichts über die Implementierungsdetails von Restangular wissen, außer dem, was er zurückgibt, genau wie Ihr Service.

Mock Beispiel:

var Restangular = { 
    all: function() { 
    return { 
     get: function() { 
     restangularDeferred = $q.defer(); 
     return restangularDeferred.promise; 
     } 
    }; 
    } 
}; 

Jetzt können Sie leicht entweder auflösen oder restangularDeferred ablehnen je nachdem, was Sie testen möchten.

Richten Sie Ihr Modul die Mock zu verwenden:

module('myApp', function($provide) { 

    $provide.value('Restangular', Restangular); 
}); 

Beispiel Testerfolgsfall:

it('success', function() { 

    // If you want you can still spy on the mock 
    spyOn(Restangular, 'all').and.callThrough(); 

    var mockResponse = {}; 

    var promise = myServices.getAccount('account123'); 

    promise.then(function(response) { 

    expect(response).toEqual(mockResponse); 
    expect(Restangular.all).toHaveBeenCalledWith('Some/Url/Path'); 
    }); 

    restangularDeferred.resolve(mockResponse); 

    // Trigger the digest loop and resolution of promise callbacks 
    $rootScope.$digest(); 
}); 

Beispiel Test Fehlerfall:

it('error', function() { 

    spyOn(anotherService, 'someMethodCall'); 

    var mockResponse = {}; 

    myServices.getAccount('acount123'); 

    restangularDeferred.reject(mockResponse); 

    $rootScope.$digest(); 

    expect(anotherService.someMethodCall).toHaveBeenCalled(); 
}); 

Beachten Sie, dass ich im Beispiel someMethodCall in anotherService verschoben.

Demo:http://plnkr.co/edit/4JprZPvbN0bYSXFobgmu?p=preview

+0

Thank you !! Funktioniert perfekt – noobprogrammer

+0

@noobprogrammer Gern geschehen :) – tasseKATT

Verwandte Themen