Sinon: Envolva getters e setters ES5

Criado em 3 mar. 2012  ·  23Comentários  ·  Fonte: 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 suportar getters e setters, você precisa fazer um Object.getOwnPropertyDescriptor(obj, prop) para o objeto e, em seguida, um Object.getPrototypeOf(obj) recursivo se ele não existir, o descritor tem um 'get' e 'set' propriedade onde eles são definidos.

Mas, você pode querer simular apenas o getter ou apenas o setter ou ambos, então como você especifica isso? Algumas opções:

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

E também, você já tem uma convenção em vigor para lidar com recursos que podem não estar presentes no ambiente atual? Se alguém tentar fazer isso no IE6, o que deve acontecer?

Comentários muito úteis

Um caso de uso que não é incomum é quando um getter é fornecido, mas um setter não, o que torna a propriedade somente leitura, o que pode ser uma boa ideia para código de produção, mas atrapalha o teste. Ter os getters e setters de suporte da Sinon falaria com esse caso de uso.

Todos 23 comentários

Olhando para seus exemplos, não tenho certeza de que simular getters seja uma boa prática de teste - eu presumiria que simplesmente definir a propriedade para algum valor durante o teste seria uma grande ajuda na maioria dos casos (?)

De qualquer forma, e se o stub for um objeto em vez de uma função, ele será tratado como um descritor de propriedade? Algo como:

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

No entanto, não tenho certeza de como resolver suas expectativas. Mas como eu disse - mas vale a pena colocar expectativas simuladas em pesquisas de propriedades? Parece-me que, se precisar disso, talvez devam ser métodos "reais" em vez disso?

O exemplo era simplista. O código real no qual eu estava tentando fazer isso era chamado de get identifier que acrescentava algumas coisas, algumas das quais vieram de lugares com os quais eu não queria me preocupar no teste, eu só queria confirmar que x.identifier foi acessado e então tem controle sobre o que foi retornado. Por enquanto, vou com getIdentifier() que é bom, mas, como podemos ver mais getters e setters no futuro para propriedades computadas, isso pode ser algo que a Sinon poderia / deveria tratar?

Ainda estou meio indeciso sobre isso. Vou deixar descansar um pouco e decidir depois. Se você tiver mais sugestões / sugestões, sinta-se à vontade para anotá-las aqui.

Um caso de uso que não é incomum é quando um getter é fornecido, mas um setter não, o que torna a propriedade somente leitura, o que pode ser uma boa ideia para código de produção, mas atrapalha o teste. Ter os getters e setters de suporte da Sinon falaria com esse caso de uso.

Por enquanto, não vejo valor em apoiar getters e setters no Sinon.

obviamente, já faz um tempo que esse problema foi discutido, mas esse recurso seria muito útil ...

+1
Eu também sinto falta disso. Seria especialmente útil quando usado com componentes que funcionam como abstrações com getters sobre algum recurso subjacente, como arquivos ou objetos de banco de dados. Seria bom ser capaz de fazer stub nesses getters.

Eu também gostaria de ver isso reaberto. Seria útil especificamente para campos de stub de um objeto de localização empacotado.

1 para esse recurso!

: +1: Eu também senti a necessidade desse recurso.

: +1: Isso precisa ser reaberto. Especialmente com o ES6 em recuperação, isso é mais importante do que nunca. Eu gosto da variante expectsGet .

+1 Concordo totalmente com @simonzack

+1

Eu também gostaria de ver isso reaberto. Seria útil especificamente para campos de stub de um objeto de localização empacotado.

Https://github.com/mroderick/wrapple preenche essa lacuna para você?

Hoje em dia eu uso wrapple bastante e esqueci de comentar sobre esse assunto. Isso provavelmente significa que o wrapple preencheu a lacuna, como você disse.

+1 acabou de tropeçar em sinon não apoiando a zombaria de getter

Olá @derwaldgeist , você está usando a versão mais recente do Sinon?

O mais recente suporta getters de stub com sandboxes e sinon.stub .

Tudo que você precisa fazer é usar a função get , por exemplo:

var myObj = {
    prop: "foo"
};

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

myObj.prop // "bar"

Por favor, deixe-me saber se isso se adequa ao seu caso de uso ou se você tiver mais dúvidas.

Obrigado por voltar tão rápido, muito apreciado.
No entanto, não descobri como restaurar um getter que foi definido dessa forma. Eu até olhei para o código-fonte do sinon e não pude ver um mecanismo que armazena o getter original ao chamar get ().

Olá @derwaldgeist ,

De fato, é possível restaurar getters, mesmo se eles fossem indefinidos antes de serem fragmentados. Tudo que você precisa fazer é chamar o método restore no stub criado, por exemplo:

var myObj = {
    prop: "foo"
};

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

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

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

Nós adicione restore método que seja em o stub método em si (quando arrancar uma propriedade não-função) ou no wrapMethod utilidade .

Uau, isso foi rápido. Eu tentei isso:

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

mas ao executar restore () diz: Cannot redefine property: prop

De onde vem o seu método createStub ?

@derwaldgeist Peguei isso em um teste, desculpe, esqueci de editá-lo. Mas de qualquer maneira, é o mesmo que sinon.stub .

Você pode me dizer qual versão do sinon você está usando para que eu possa verificar?

Acho que talvez você não esteja usando a versão mais recente, na qual corrigimos um bug em que não era possível restaurar as propriedades devido a elas terem sido definidas sem configurable: true e, portanto, não foi possível alterar seus descritores.

Estou vendo o mesmo que @derwaldgeist. _Penso_ que estou usando a v4, mas alguns outros departamentos estavam usando a v1.7, então não tenho certeza de qual está _realmente_ sendo usada. Não vi um sinon.version que pudesse verificar em tempo de execução.

@ jshado1 Se quiser saber em qual versão principal você está, consulte o log de mudanças ou o guia de migração e teste as alterações mais recentes. Para a versão 4, você pode afirmar que sinon.stub({}, 'nonExistingProperty') lança

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

akdor1154 picture akdor1154  ·  4Comentários

brettz9 picture brettz9  ·  3Comentários

stephanwlee picture stephanwlee  ·  3Comentários

JakobJingleheimer picture JakobJingleheimer  ·  3Comentários

sudhirbits picture sudhirbits  ·  4Comentários