javascript - test - karma js
¿Cómo puedo espiar una propiedad getter usando jazmín? (6)
Creo que la mejor manera es usar spyOnProperty
. Espera 3 propiedades y necesita pasar o set
como tercera propiedad.
spyOnProperty(o, ''foo'', ''get'').and.returnValue(''bar'');
¿Cómo puedo espiar una propiedad getter usando jazmín?
var o = { get foo() {}, };
spyOn(o, ''foo'').and.returnValue(''bar''); // Doesn''t work.
Esto tampoco funciona AFAICT:
spyOn(Object.getOwnPropertyDescriptor(o, ''foo''), ''get'').and.returnValue(''bar'');
Desde Jasmine 2.6, esto ha sido posible con spyOnProperty
. Para espiar los accesadores para la propiedad foo
, haga lo siguiente:
spyOnProperty(o, ''foo'')
Esto le permite reemplazar el set
y / o get
funciones de acceso para una propiedad de acceso con una función de espionaje. Puede especificar o set
o get
solo como un tercer argumento:
spyOnProperty(o, ''foo'', ''get'')
Si está atrapado usando una versión anterior y no puede actualizar por algún motivo, puede fusionar la solicitud de extracción que agregó esta función en su copia local del código.
En febrero de 2017, combinaron un RP que agregaba esta función, la lanzaron en abril de 2017.
para espiar los getters / setters que usa: const spy = spyOnProperty(myObj, ''myGetterName'', ''get'');
donde myObj es su instancia, ''myGetterName'' es el nombre definido en su clase como get myGetterName() {}
y el tercer param es el tipo get
o set
.
Puedes usar las mismas afirmaciones que ya usas con los espías creados con spyOn
.
Entonces puedes por ejemplo:
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.
Aquí está la línea en el código fuente de Github donde este método está disponible si está interesado.
Respondiendo a la pregunta original, con jazmín 2.6.1, usted:
var o = { get foo() {} };
spyOnProperty(o, ''foo'', ''get'').and.returnValue(''bar'');
Me inspiré en la respuesta de @apsillers y escribí el siguiente ayudante (requiere que el accesorio sea configurable como se mencionó anteriormente)
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;
}
Y se puede usar así:
import { spyOnGetter } from spyExtra;
it(''tests the thing'', () => {
spyOnGetter(myObj, ''myProp'').and.returnValue(42);
expect(myObj.myProp).toBe(42);
});
Espero que sea útil!
No creo que puedas espiar a los getters. El objetivo de un getter es que actúe exactamente como una propiedad, entonces, ¿cómo podría jazmín espiarlo cuando nunca se llama como una función sino que se accede como una propiedad?
Como solución alternativa, puede hacer que su getter llame a otra función y espiar eso en su lugar.
var o = {
_foo: function(){
return ''foo'';
},
get foo(){
return this._foo();
}
};
spyOn(o, ''_foo'').and.returnValue(''bar'');
Puede hacer esto si no puede usar el último jazmín (2.6.1)
const getSpy = jasmine.createSpy().and.returnValue(''bar'')
Object.defineProperty(o, ''foo'', { get: getSpy });
Documentación para defineProperty, here