La méthode spyOn
de Jasmine permet de modifier le comportement d'une méthode, mais existe-t-il un moyen de modifier une propriété de valeur (plutôt qu'une méthode) pour un objet? le code pourrait être comme ci-dessous:
spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
En février 2017, ils ont fusionné un RP en ajoutant cette fonctionnalité, qu'ils ont publiée en avril 2017.
pour espionner les accesseurs que vous utilisez: const spy = spyOnProperty(myObj, 'myGetterName', 'get');
où myObj est votre instance, 'myGetterName' est le nom de celle définie dans votre classe comme get myGetterName() {}
et le troisième paramètre est le tapez get
ou set
.
Vous pouvez utiliser les mêmes assertions que vous utilisez déjà avec les espions créés avec spyOn
.
Donc vous pouvez par exemple:
const spy = spyOnProperty(myObj, 'myGetterName', 'get'); // to stub and return nothing. Just spy and stub.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.returnValue(1); // to stub and return 1 or any value as needed.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.callThrough(); // Call the real thing.
Voici la ligne du code source de github où cette méthode est disponible si vous êtes intéressé.
En répondant à la question initiale, avec jasmine 2.6.1, vous pouvez:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Jasmine ne possède pas cette fonctionnalité, mais vous pourrez peut-être pirater quelque chose ensemble à l'aide de Object.defineProperty
.
Vous pouvez refactoriser votre code pour utiliser une fonction getter, puis espionner le getter.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
Une raison pour laquelle vous ne pouvez pas simplement le changer directement sur l'objet? Ce n'est pas comme si javascript imposait la visibilité d'une propriété sur un objet.
Le meilleur moyen est d'utiliser spyOnProperty
. Il attend 3 paramètres et vous devez passer get
ou set
en tant que troisième paramètre.
const div = fixture.debugElement.query(By.css('.Ellipsis-overflow'));
// now mock properties
spyOnProperty(div.nativeElement, 'clientWidth', 'get').and.returnValue(1400);
spyOnProperty(div.nativeElement, 'scrollWidth', 'get').and.returnValue(2400);
Ici, je mets le get
de clientWidth
de div.nativeElement
objet.
Si vous utilisez ES6 (Babel) ou TypeScript, vous pouvez tronquer la propriété à l'aide des accesseurs get et set.
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
Ensuite, dans votre test, vous pouvez vérifier que la propriété est définie avec:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
J'utilise une grille de kendo et je ne peux donc pas utiliser une méthode getter pour l'implémentation, mais je souhaite tester cette possibilité (se moquer de la grille) et ne pas tester la grille elle-même. J'utilisais un objet espion mais ceci ne supporte pas la propriété moqueuse alors je le fais:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
C'est un peu long mais ça marche un régal
La bonne façon de faire est d’espionner les propriétés, cela vous permettra de simuler une propriété sur un objet avec une valeur spécifique.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Supposons qu’une méthode comme celle-ci nécessite des tests. La propriété src
de la petite image doit être vérifiée.
function reportABCEvent(cat, type, val) {
var i1 = new Image(1, 1);
var link = getABC('creosote');
link += "&category=" + String(cat);
link += "&event_type=" + String(type);
link += "&event_value=" + String(val);
i1.src = link;
}
Le spyOn () ci-dessous provoque l'alimentation de la "nouvelle image" avec le faux code à partir du test. Le code spyOn renvoie un objet qui n'a qu'une propriété src.
Comme la variable "hook" est visible pour être visible dans le faux code dans le SpyOn et aussi plus tard après que le "reportABCEvent" soit appelé
describe("Alphabetic.ads", function() {
it("ABC events create an image request", function() {
var hook={};
spyOn(window, 'Image').andCallFake( function(x,y) {
hook={ src: {} }
return hook;
}
);
reportABCEvent('testa', 'testb', 'testc');
expect(hook.src).
toEqual('[zubzub]&arg1=testa&arg2=testb&event_value=testc');
});
Ceci est pour jasmine 1.3 mais peut fonctionner en 2.0 si "andCallFake" est modifié en nom 2.0
Je sais que je suis un peu en retard à la fête, mais
Vous pouvez accéder directement à l'objet call, qui peut vous donner les variables pour chaque appel
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)