2016-05-11 9 views
1

Ich bin versucht, einige Antworten von einem http Anruf von Angular in meinen Jasmin Tests zu verspotten.Mocking Angular http-Antwort mit Jasmin geht nicht in Callback-Funktion

Ich habe einen Dienst namens ‚Imageservice‘ und dies hat eine Funktion ‚create‘ genannt. Ich spioniere aus und erstelle ein zurückgewiesenes Versprechen, weil ich versuche, Fehler zu testen.

Hier ist mein Service:

this.create = function(image) { 
    return imageApi.post(image); 
}; 

Die imageApi Variable ist eine Restangular Instanz.

Mein Test sieht wie folgt aus:

spyOn(ImageService, 'create').and.callFake(function() { 
    var deferred = $q.defer(); 
    deferred.reject({ 
     data: { 
      status: 400, 
      errors: { 
       "image.fileNotImage": "File uploaded is not an image." 
      } 
     } 
    }); 
    return deferred.promise; 
}); 

Obwohl ich dieses Versprechen werde Ablehnung es nicht seinen Weg in den Fehler-Callback meiner Controller macht. Der Anruf von meinem Controller sieht so aus.

ImageService.create(formData) 
    .then(function(response) { 
     console.log(response); 
       vm.imagePreview = response; 
       createAdMedia(adMedia, response.fileURL); 
     }, function(error) { 
       console.log(error); 
       /** 
       * If we get no data then we can assume its a 500 or 
       * 405 error so we give a generic error message 
       */ 
       if (error.data.errors) { 
        var errors = error.data.errors; 
        for (var key in errors) { 
         showMessage("errorMessage", DWIN.i18n.t(errors[key])); 
        } 
       } else { 
        showMessage("errorMessage", DWIN.i18n.t("merchant.admedia.failure")); 
       } 
     }); 

Kann jemand ein Problem damit sehen?

Danke!

+0

Können zeigen Sie uns mehr von dem Test-Code? der ganze Test selbst ich meine, dass Jasmin Erwartungen – sam

+4

Ich vermute, Sie verwendet keinen $ Digest() im Test zu tun, was bedeuten würde, dass Winkel nie das HTTP-Aufruf – sam

+0

@ Sam, das ist auslöst, ist wahr, ich bin es nicht. Ich werde das versuchen. Muss der Aufruf von $ digest() aufgerufen werden, nachdem der Spion eingerichtet wurde? –

Antwort

1

Sie nicht den vollständigen Code des Tests geben, aber ich vermute, dass Sie einen $ Digest() oder $ auszuführen weggelassen apply() nach dem Service-Funktion aufrufen. Ohne diesen Winkel wird keine automatische Funktion ausgeführt, die normalerweise ausgeführt wird, weil Sie sich in einer Testumgebung und nicht in der laufenden App befinden.

Hier ist ein Beispiel dafür, wie Sie $ q einfacher mit $ Digest() kombinieren kann, unter der Annahme, dass Sie einen Controller testen, die diese create Methode verwendet:

beforeEach(inject(function ($rootScope, $controller, _$q_, _YourService_) { 
    $scope = $rootScope.$new(); 
    $q = _$q_; 
    YourService = _YourService_; 

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

it('Should do something', function() { 
    spyOn(YourService, 'create').and.returnValue($q.reject({data: yourdata})); 

    YourController.theMethodThasUsesCreate(); 
    $scope.$digest(); 

    expect(something).toHaveBeenCalled(); 
}); 
+0

Ja, um den Anruf Hinzufügen funktionierte perfekt zu verdauen. Danke für die Erklärung, wirklich geholfen. –

+0

@DavidJones eine Anmerkung: nicht vergessen, dass es nur einen einzigen Winkelzyklus auslöst, was bedeutet, wenn Sie verspricht in Kaskade oder Intervall/Timeout tun Testen Sie den Digest aufrufen müssen oder Verfahren mehrmals im gleichen Test – sam

+0

groß gelten, Danke für die Information! –

1

Einige Proof of Concept ohne alle stubbing Sachen/Methoden.

angular.module('image', []) 
 
    .service('ImageService', function($q) { 
 
    this.create = function() { 
 
     return $q.when(); 
 
    } 
 
    }) 
 
    .controller('ImageCtrl', function(ImageService) { 
 
    ImageService.create() 
 
     .then(function(response) {}, function(error) { 
 
     console.error('error', error); 
 
     }); 
 
    }); 
 

 

 
describe('ImageCtrl', function() { 
 

 
    var $scope; 
 

 
    beforeEach(module('image')) 
 

 
    beforeEach(inject(function($rootScope) { 
 
    $scope = $rootScope.$new() 
 
    })) 
 

 
    it('ImageService.create() - supports rejection', inject(function($controller, $q, ImageService) { 
 
    var errorMessage = {data: {error: 'some error message'}} 
 
    spyOn(ImageService, 'create').and.returnValue($q.reject(errorMessage)) 
 
    spyOn(console, 'error') 
 
    
 
    $controller('ImageCtrl', { 
 
     $scope: $scope 
 
    }); 
 
    
 
    $scope.$digest(); 
 
    
 
    expect(console.error).toHaveBeenCalledWith('error', errorMessage) 
 
    })) 
 
})
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" /> 
 
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>