Sinon: Encadenar sinon.stub() con múltiples .withArgs solo stubs la última declaración

Creado en 25 sept. 2012  ·  23Comentarios  ·  Fuente: sinonjs/sinon

Encadenar sinon.stub() con múltiples .withArgs solo stubs la última declaración

var stubbedFunction = sinon.stub().withArgs(argumento1).returns(valor1).withArgs(argumento2).returns(valor2);

entonces solo la última declaración (.withArgs(argument2).returns(value2)) es realmente tachada

Comentario más útil

Esto funciona correctamente con Sinon 1.7.3:

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined

Todos 23 comentarios

Necesita hacer que withArgs modifique y devuelva el código auxiliar original desde el que se creó, cuando esté disponible.

+1 por esto. En una nota relacionada, me gustaría que withArgs permita opcionalmente pasar al método original para argumentos no coincidentes.

Por ejemplo, si quiero agregar el método Node.js fs.readFileSync() , quiero que Sinon conserve la implementación original para que require() (que usa readFileSync ) no se rompa, pero use el método stubbed para un archivo en particular para mis pruebas.

Ejemplo del comentario anterior:

beforeEach(function() {
  global.fs = require('fs');
  sinon.stub(fs, 'readFileSync').onlyWithArgs('my-file.txt').returns('Contents of file');

  // Then require the module under test, which uses fs.readFileSync() internally
  // require() uses original method with correct calling context
  global.myModule = require('../src/my-module');
});

afterEach(function() {
  fs.readFileSync.restore();
});

it('does something with the file', function() {
  expect(myModule.loadFromFile()).toEqual('Contents of file');
});

Me gustaría sugerir que la publicación anterior de @froots se publique en algún lugar de los documentos. Busqué durante mucho tiempo antes de encontrar esta solución sobre cómo simular archivos que incluyen otras dependencias a través require

Buena idea. ¿Quieres intentarlo? http://github.com/cjohansen/sinon-web/

Esto funciona correctamente con Sinon 1.7.3:

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined

No creo que sea un ejemplo de que funcione, ya que todavía no se encadena (tienes que usar el stub/simulacro original).

Cierto. Pero es lo suficientemente bueno y deja en claro lo que está pasando. El encadenamiento deja espacio para la interpretación.

Estoy de acuerdo con @mantoni. El stub tiene como finalidad indicar la respuesta contractual del servicio/consulta. Este estilo lo expresa mejor.

Creo que los documentos probablemente podrían mejorarse aquí.

Esperaba que funcionara lo siguiente:

var someObj = {
    someProp: sinon.stub().withArgs("foo").returns(true)
}

Obviamente no funcionó como se esperaba. Pero, más importante aún, no falló correctamente. En lugar de que someObj.someProp no devuelva verdadero cuando no se proporciona foo , siempre devuelve true . Dado que la cláusula returns devuelve una instancia de Comportamiento, someObj.someProp devuelve debidamente true independientemente de la entrada.

Entiendo la lógica detrás de la estructura de encadenamiento que devuelve diferentes tipos de objetos. Pero los usuarios son engañados sobre cuáles son esos objetos devueltos. Dado que los métodos que exponen CallObjects y Behaviors coinciden con la API proporcionada por Stubs, es fácil ver por qué uno supondría que _eran_ stubs.

Estoy de acuerdo con @jasonkarns. Acabo de caer en la misma "trampa": insertar la declaración de stub no devuelve la instancia de stub esperada. Sin embargo, el encadenamiento parece funcionar como se esperaba cuando se usan simulacros:

var someObj = {
    someProp: sinon.mock().withArgs("foo").returns(true)
}

Hay alguna razón para esto?

No estoy seguro de si me estoy perdiendo algo, pero ¿es posible el punto @froots ahora? Tuve que hacer esto:

sinon.stub(fs, 'readdirSync', (dir) => {
    if (dir === 'foo-path') {
        return [
            'my.js',
            'fake.js',
            'stuff.js'
        ];
    }

    return fsReaddir(dir);
});

Quería hacer algo como:

var myStub = sinon.stub(fs, 'readdirSync', fs.readdirSync);

myStub
    .withArgs('foo-path')
    .returns([
        'my.js',
        'fake.js',
        'stuff.js'
    ]);

Creo que esto está solucionado ahora, el siguiente ejemplo funciona según lo previsto con [email protected]

var Dummy = {
    doSomething: function(something) {
        return 'doing ...' + something;
    }
}

sinon.stub(Dummy, 'doSomething')
    .withArgs('sleep').returns('sleepy')
    .withArgs('eat').returns('eating');

console.log(Dummy.doSomething('sleep'));
console.log(Dummy.doSomething('eat'));

@valentin-radulescu-hs todavía falla de mi lado con 1.17.7 .
Todavía toma el último returns como el único valor de retorno, independientemente del withArgs (como lo señaló @jasonkarns https://github.com/sinonjs/sinon/issues/176#issuecomment- 78191790).

Lo que funciona para mí es la respuesta de @mantoni https://github.com/sinonjs/sinon/issues/176#issuecomment -33636496, al no encadenar withArgs() .

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');

@zurfyx , ¿está ejecutando en el nodo o en el navegador? ¿Qué versión de nodo/navegador estás usando? No estoy seguro de si importa, pero me gustaría intentar replicar por mi parte.

Hola @valentin-radulescu-hs. Lo estoy ejecutando en Node, usando babel-cli 6.22.2

  • Nodo 6.9.4
  • MNP 3.10.10

lo siento por la respuesta tardía

@zurfyx Intenté replicar con la configuración que mencionó usando el mismo código que escribí anteriormente y sale a la consola sleepy y eating como se esperaba. No estoy seguro de por qué te está causando problemas 😢

@zurfyx Solo para estar _totalmente_ seguro, ¿has probado esto?

grep version node_modules/sinon/package.json
rm -r node_modules
rm npm-shrinkwrap
npm install
grep version node_modules/sinon/package.json

La mayoría de las veces que tengo problemas se debe a que la versión del paquete que espero no es la misma que está instalada.

@ fatso83 Tampoco funciona. La versión de salida grep sigue siendo 1.1.7.7 .

Esta es mi prueba completa, en caso de que pueda ayudar:

  it('test', () => {
    const s = sinon.stub();
    s.withArgs('a').returns('1');
    s.withArgs('b').returns('2');

    console.info(s('c'));
  });

s('a') : '1'
s('b') : '2'
s('c') : undefined

  it('test', () => {
    const s = sinon.stub()
      .withArgs('a').returns('1')
      .withArgs('b').returns('2');

    console.info(s('c'));
  });

s('a') : '2'
s('b') : '2'
s('c') : '2'

Puedo reproducir este comportamiento usando sinon.createStubInstance también.

const stub = sandbox.stub();
      const myObj = function(){};
      const objOne = sinon.createStubInstance(myObj);
      const objTwo = sinon.createStubInstance(myObj);
      stub.withArgs(objOne).returns('1');
      stub.withArgs(objTwo).returns('2');

      console.info(stub(objOne));
      console.info(stub(objTwo));

Producción:
2 2

Pensé que se suponía que sinon.createStubInstance crearía un nuevo objeto de código auxiliar. ¿Es eso incorrecto?

No estoy completamente seguro de si esta pregunta pertenece a este hilo, pero definitivamente tiene algo que ver con eso. En un proyecto con sinon 1.17.7 , solía encadenar varias declaraciones withArgs , donde la última era un comparador "agarrar todo" que actuaba como predeterminado. Por ejemplo:

const s = sinon.stub();
s.withArgs(1).returns(1)
 .withArgs(2).returns(2)
 .withArgs(sinon.match.any).returns('my-default-value')

s(1) // 1
s(5) // my-default-value

Ahora estoy usando 4.1.3 y el comportamiento cambió, siempre devuelve my-default-value . ¿Fue esto intencionado? Si es así, ¿hay alguna forma de definir un valor predeterminado/de respaldo en una cadena de withArgs ?

No creo que nunca se pretendiera un cambio. Si puede proporcionar una solución para el
regresión siéntase libre! Puedo ayudar a rastrear dónde sucedió usando got
culpar.

hombre de la guarida. 15. ene. 2018, 11.13 Skrev David García [email protected] :

No estoy completamente seguro de si esta pregunta pertenece a este hilo, pero
definitivamente tiene algo que ver con eso. En un proyecto con sinon 1.17.7 I
solía encadenar varias sentencias withArgs, donde la última era una
emparejador "agarrar todo" que actuó como predeterminado. Por ejemplo:

const s = sinon.stub();s.withArgs(1).returns(1)
.withArgs(2).devoluciones(2)
.withArgs(sinon.match.any).returns('mi-valor-predeterminado')
s(1) // 1s(5) // mi-valor-predeterminado

Ahora estoy usando 4.1.3 y el comportamiento cambió, siempre regresa
mi-valor-predeterminado. ¿Fue esto intencionado? Si es así, ¿hay alguna manera de definir un
valor predeterminado/de reserva en una cadena de withArgs?


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/sinonjs/sinon/issues/176#issuecomment-357638653 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAluXMzqALJ0JlAM3hUaiK1SSyca9H74ks5tKyS4gaJpZM4AK2eu
.

>

[imagen: --]

Carl-Erik Kopseng
[imagen: https://]about.me/kopseng
https://about.me/kopseng?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links

@ fatso83 Lo reduje y aparentemente fue a propósito . Para mí, se siente más natural especificar un respaldo en la última instrucción withArgs , aunque en este caso solo cambiar el orden y colocar .withArgs(sinon.match.any) en la primera posición resuelve el problema.

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