Comment puis-je espionner une propriété getter en utilisant du jasmin?
var o = { get foo() {}, };
spyOn(o, 'foo').and.returnValue('bar'); // Doesn't work.
Cela ne fonctionne pas non plus AFAICT:
spyOn(Object.getOwnPropertyDescriptor(o, 'foo'), 'get').and.returnValue('bar');
Depuis Jasmine 2.6, cela a été possible avec spyOnProperty
. Pour espionner les accesseurs de la propriété foo
, procédez comme suit:
spyOnProperty(o, 'foo')
Cela vous permet de remplacer les fonctions d'accesseur set
et/ou get
d'une propriété d'accesseur par une fonction d'espionnage. Vous pouvez spécifier ou set
ou get
uniquement comme troisième argument:
spyOnProperty(o, 'foo', 'get')
Si vous êtes bloqué en utilisant une version antérieure et ne pouvez pas mettre à niveau pour une raison quelconque, vous pourrez peut-être fusionner le demande d'extraction qui a ajouté cette fonctionnalité dans votre copie locale du code.
En février 2017, ils ont fusionné un PR en ajoutant cette fonctionnalité, ils l'ont sorti en avril 2017.
donc pour espionner les getters/setters vous utilisez: const spy = spyOnProperty(myObj, 'myGetterName', 'get');
où myObj est votre instance, 'myGetterName' est le nom de celui défini 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
.
Vous pouvez donc 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 github où cette méthode est disponible si vous êtes intéressé.
En répondant à la question d'origine, avec le jasmin 2.6.1, vous feriez:
var o = { get foo() {} };
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
Je me suis inspiré de la réponse de @apsillers et j'ai écrit l'aide suivante (nécessite que l'accessoire soit configurable comme mentionné ci-dessus)
let activeSpies = [];
let handlerInstalled = false;
function afterHandler() {
activeSpies.forEach(({ obj, prop, descriptor }) => Object.defineProperty(obj, prop, descriptor));
activeSpies = [];
}
export function spyOnGetter(obj, prop) {
const env = jasmine.getEnv();
const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
const spy = jasmine.createSpy(`${prop} spy`);
const copy = Object.assign({}, descriptor, { get: spy });
Object.defineProperty(obj, prop, copy);
activeSpies.Push({
obj,
prop,
descriptor,
});
if (!handlerInstalled) {
handlerInstalled = true;
env.afterEach(() => afterHandler());
}
return spy;
}
Et il peut être utilisé comme ceci:
import { spyOnGetter } from spyExtra;
it('tests the thing', () => {
spyOnGetter(myObj, 'myProp').and.returnValue(42);
expect(myObj.myProp).toBe(42);
});
J'espère que c'est utile!
Je pense que la meilleure façon est d'utiliser spyOnProperty
. Il attend 3 propriétés et vous devez passer get
ou set
comme troisième propriété.
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
Vous pouvez le faire si vous ne pouvez pas utiliser le dernier jasmin (2.6.1)
const getSpy = jasmine.createSpy().and.returnValue('bar')
Object.defineProperty(o, 'foo', { get: getSpy });
Documentation pour defineProperty, ici