Sinon: Envuelva getters y setters de ES5

Creado en 3 mar. 2012  ·  23Comentarios  ·  Fuente: sinonjs/sinon

var o = {
  get foobar() { return 'foobar' },
  set foobar(s) { throw 'bzzt!' },
  foo: function() { return 'foo' },
  bar: 'bar'
}; // -> { foobar: [Getter/Setter], foo: [Function], bar: 'bar' }

sinon.mock(o).expects('foobar').returns('woohoo'); // doesn't because sinon.wrapMethod() does an object[property] which accesses the getter which returns a string

Para admitir getters y setters, debe hacer un Object.getOwnPropertyDescriptor(obj, prop) para el objeto y luego un Object.getPrototypeOf(obj) recursivo si no existe, el descriptor tiene 'get' y 'set' propiedad donde están definidos.

Pero, es posible que desee simular solo el captador o solo el configurador o ambos, entonces, ¿cómo especifica eso? Algunas opciones:

mock(o).expects('foobar'); // ambiguous, the setter? getter? or both?
mock(o).expects('get foobar'); // ambiguous, there may be a legitimate property named "get foobar"
mock(o).expectsGet('foobar'); // clear but more code in Sinon and more to document ?
mock(o).expectsSet('foobar'); // ditto

Y también, ¿ya tiene una convención para tratar con características que pueden no estar presentes en el entorno actual? Si alguien intenta hacer esto en IE6, ¿qué debería suceder?

Comentario más útil

Un caso de uso que no es infrecuente es donde se proporciona un captador pero no un definidor, lo que hace que la propiedad sea de solo lectura, lo que puede ser una buena idea para el código de producción, pero obstaculiza las pruebas. Tener a los captadores y definidores de soporte de Sinon hablaría de ese caso de uso.

Todos 23 comentarios

Al observar sus ejemplos, no estoy del todo seguro de que burlarse de los captadores sea una buena práctica de prueba; supongo que simplemente establecer la propiedad en algún valor durante la duración de la prueba sería de gran ayuda en la mayoría de los casos (?)

De todos modos, ¿qué pasa si el stub es un objeto en lugar de una función, se tratará como un descriptor de propiedad? Algo como:

stub(o, "foobar", { get: function () { return 42; } });

Sin embargo, no estoy seguro de cómo resolver sus expectativas. Pero como dije, ¿vale la pena poner expectativas simuladas en las búsquedas de propiedades? Me parece que si lo necesita, ¿quizás deberían ser métodos "reales" en su lugar?

El ejemplo fue simplista. El código real en el que estaba tratando de hacer esto se llamaba get identifier que adjuntaba algunas cosas juntas, algunas de las cuales provenían de lugares con los que no quería molestarme en la prueba, solo quería confirmar eso Se accedió a x.identifier y luego tener control sobre lo que se devolvió. Por ahora, voy con un getIdentifier() que está bien, pero dado que es posible que veamos más captadores y definidores en el futuro para propiedades calculadas, esto puede ser algo que Sinon podría / debería manejar.

Todavía un poco indeciso sobre esto. Lo dejaré reposar un rato y luego decidirá. Si tiene más comentarios / sugerencias, no dude en anotarlos aquí.

Un caso de uso que no es infrecuente es donde se proporciona un captador pero no un definidor, lo que hace que la propiedad sea de solo lectura, lo que puede ser una buena idea para el código de producción, pero obstaculiza las pruebas. Tener a los captadores y definidores de soporte de Sinon hablaría de ese caso de uso.

Por el momento, no veo el valor de apoyar a los getters y setters en Sinon.

obviamente, ha pasado un tiempo desde que se discutió este tema, pero esta característica sería muy útil ...

+1
También lo extraño. Sería especialmente útil cuando se usa con componentes que funcionan como abstracciones con captadores sobre algún recurso subyacente, como archivos u objetos de base de datos. Sería bueno poder aplastar a esos captadores.

También me gustaría ver esto reabierto. Sería útil específicamente para apuntar campos de un objeto de ubicación envuelto.

+1 para esa función.

: +1: También sentí la necesidad de esta función.

: +1: Esto debe volver a abrirse. Especialmente ahora que ES6 se está poniendo de moda, esto es más importante que nunca. Me gusta la variante expectsGet .

+1 Estoy totalmente de acuerdo con @simonzack

+1

También me gustaría ver esto reabierto. Sería útil específicamente para apuntar campos de un objeto de ubicación envuelto.

¿ Https://github.com/mroderick/wrapple cubre esa brecha por ti?

Hoy en día uso Wrapple de manera bastante extensa y me había olvidado de comentar sobre este tema. Eso probablemente significa que Wrapple ha tapado la brecha como usted dice.

+1 acaba de tropezar con sinon que no apoya las burlas de getter

Hola @derwaldgeist , ¿estás usando la última versión de Sinon?

El último admite getters de stubbing con sandboxes y sinon.stub .

Todo lo que tienes que hacer es usar la función get , por ejemplo:

var myObj = {
    prop: "foo"
};

createStub(myObj, "prop").get(function getterFn() {
    return "bar";
});

myObj.prop // "bar"

Hágame saber si esto se adapta a su caso de uso o si tiene más dudas.

Gracias por regresar tan rápido, muy apreciado.
Sin embargo, no encontré cómo se puede restaurar un getter que se ha definido de esa manera. Incluso miré el código fuente de sinon y no pude ver un mecanismo que almacena el captador original al llamar a get ().

Hola @derwaldgeist ,

De hecho, es posible restaurar getters, incluso si no estaban definidos antes de ser eliminados. Todo lo que tienes que hacer es llamar al método restore en el código auxiliar creado, por ejemplo:

var myObj = {
    prop: "foo"
};

var stub = createStub(myObj, "prop");

stub.get(function getterFn() {
    return "baz";
});

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

Agregamos este método restore que ya sea en el método en la utilidad wrapMethod .

Vaya, eso fue rápido. Intenté esto:

 const stub = sinon.stub(myObj, 'prop');
 stub.get(() => ({}));
  ...
 stub.restore();

pero al ejecutar restore () dice: Cannot redefine property: prop

¿De dónde proviene su método createStub ?

@derwaldgeist Lo obtuve de una prueba, lo siento, olvidé editarlo. Pero de todos modos, es lo mismo que sinon.stub .

¿Puedes decirme qué versión de sinon estás usando para que pueda verificarlo?

Creo que tal vez aún no esté utilizando la última versión en la que corregimos un error en el que no podía restaurar las propiedades debido a que estaban definidas sin configurable: true y, por lo tanto, no pudimos cambiar sus descriptores.

Veo lo mismo que @derwaldgeist. Creo que estoy usando la versión 4, pero algunos otros departamentos estaban usando la versión 1.7, así que no estoy seguro de cuál se está acostumbrando en realidad. No vi un sinon.version donde pudiera verificar en tiempo de ejecución.

@ jshado1 Si desea saber en qué versión principal se encuentra, puede consultar el registro de cambios o la guía de migración y probar los cambios importantes. Para la versión 4, puede afirmar que sinon.stub({}, 'nonExistingProperty') arroja

¿Fue útil esta página
0 / 5 - 0 calificaciones