2017-10-20 13 views
3

Je vous écris un test unitaire à une méthode qui contient ce morceau de code:Comment se moquer des promesses enchaînées en utilisant Jasmine?

Name.get($scope.nameId).then(function(name){ 
    Return name; 
}).then(doSomething); 

Le function doSomething(name) ressemble à ceci.

function doSomething(name){ 
    addNametoList(name); 
} 

Je n'ai pas besoin de tester cette partie du code. Puisque je ne peux pas simplement l'ignorer dans mon test (ou je peux?), Je dois me moquer de lui. Je raillé la première promesse

spyOn(mockName, 'get').and.returnValues($q.resolve({"Mike"})); 

et je pensais qu'il se propagerait à travers la seconde then(doSomething) mais name est undefined en fonction addNametoList.

Je pense que je dois aussi simuler doSomething mais je ne sais pas comment les enchaîner.

+0

Vous n'obtenez pas d'erreur? Le 'Return' avec une majuscule me semble être une faute de frappe. Comment a-t-il résolu? Rendez-vous la promesse à la fin de votre test de jasmin? – Icepickle

+0

Oui, j'ai réalisé qu'il y avait une faute de frappe dans le code. Après deux jours de débogage, j'ai finalement découvert que c'était parce que je n'avais pas correctement configuré l'objet dans $ q.resolve(). A part cela, se moquer de la première promesse se propage à la seconde '.then (doSomething)'. Merci de prendre le temps de répondre. – CiCi

+0

Il semble que vous ayez une faute de frappe - 'and.returnValues' ...ne devrait-il pas être 'and.returnValue' à la place? ** Edit: ** Nevermind, désolé, 'returnValues' existe dans les versions plus récentes de Jasmine ... – plamut

Répondre

0

Votre code de commande (partielle)

$scope.list = []; 

function addNameToList(name) { 
    $scope.list.push(name); 
} 

function doSomething(name){ 
    addNametoList(name); 
} 

$scope.functionToTest = function() { 
    Name.get($scope.nameId).then(function(name){ 
    return name; 
    }).then(doSomething); 
}; 

Votre test

it('should add the name to the list when Name.get() is resolved', function() { 
    // Arrange 
    var getDeferred = $q.defer(); 
    spyOn(mockName, 'get').and.returnValue(getDeferred.promise); 

    // Act 
    $scope.functionToTest(); 
    getDeferred.resolve('some name that should be in the list'); 
    $scope.$apply(); 

    // Assert 
    expect($scope.list).toEqual(['some name that should be in the list']); 
}); 

Commentaire

Notez que la partie suivante de votre code n'aboutit à rien et peut être supprimée sans affecter quoi que ce soit.

.then(function(name){ 
    return name; 
}) 
0

Je n'ai pas besoin de tester cette partie du code. Depuis que je ne peux pas ignorer dans mon test (ou je peux?), J'ai besoin de se moquer de lui. Je raillé la première promesse

OMI, il n'y a pas besoin de tester ces configurations dans son ensemble. Testez chaque unité individuellement.

Par exemple

A =() => { 
    ... 
} 

B =() => { 
    ... 
} 

C =() => { 
    ... 
} 

Maintenant, nous avons F, qui appelle AB & C

F =() => A(B(C)) 

Ou dans votre cas

F =() => A().then(B).then(C) 

Nous pouvons tester F, mais il faudra une certaine configuration, et être fragile. Il est préférable de test A, B & C (ce qui donne à un recouvrement parfait F) et ignorer F.