Respostas:
Em fevereiro de 2017, eles mesclaram um PR adicionando esse recurso, lançado em abril de 2017.
então, para espionar getters / setters que você usa:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
onde myObj é sua instância, 'myGetterName' é o nome daquele definido em sua classe como get myGetterName() {}
e o terceiro parâmetro é o tipo get
ou set
.
Você pode usar as mesmas afirmações que já usa com os espiões criados com spyOn
.
Então você pode, por exemplo:
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.
Esta é a linha no código-fonte do github onde esse método está disponível, se você estiver interessado.
Respondendo à pergunta original, com o jasmine 2.6.1, você:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Alguma razão pela qual você não pode simplesmente alterá-lo no objeto diretamente? Não é como se o javascript reforçasse a visibilidade de uma propriedade em um objeto.
spyOn
explicitamente indica que quero simular algo, enquanto defino diretamente a propriedade indica implicitamente que quero simular algo e não tenho certeza se alguém entenderá que estou zombando de algo quando estiver lendo o código. Outro caso é que eu não quero mudar o comportamento interno do objeto, por exemplo, se eu mudar a propriedade de comprimento de um array, o array é aparado, então uma simulação será melhor
spyOn
.
spyOn
falha no teste se a propriedade não existir.
TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
Jasmine não tem essa funcionalidade, mas você pode conseguir hackear algo junto usando Object.defineProperty
.
Você pode refatorar seu código para usar uma função getter e, em seguida, espionar o getter.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
and.returnValue(1)
A melhor forma é usar spyOnProperty
. Ele espera 3 parâmetros e você precisa passar get
ou set
como um terceiro parâmetro.
const div = fixture.debugElement.query(By.css('.ellipsis-overflow'));
// now mock properties
spyOnProperty(div.nativeElement, 'clientWidth', 'get').and.returnValue(1400);
spyOnProperty(div.nativeElement, 'scrollWidth', 'get').and.returnValue(2400);
Aqui eu estou definindo o get
de clientWidth
de div.nativeElement
objeto.
Se você estiver usando ES6 (Babel) ou TypeScript, você pode remover a propriedade usando os acessadores get e set
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
Então, em seu teste, você pode verificar se a propriedade está definida com:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
A maneira certa de fazer isso é com a propriedade do espião, que permitirá simular uma propriedade em um objeto com um valor específico.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Suponha que haja um método como este que precisa de teste A src
propriedade da imagem minúscula precisa de verificação
function reportABCEvent(cat, type, val) {
var i1 = new Image(1, 1);
var link = getABC('creosote');
link += "&category=" + String(cat);
link += "&event_type=" + String(type);
link += "&event_value=" + String(val);
i1.src = link;
}
O spyOn () abaixo faz com que a "nova imagem" seja alimentada com o código falso do teste o código spyOn retorna um objeto que tem apenas uma propriedade src
Como a variável "gancho" tem o escopo definido para ser visível no código falso no SpyOn e também mais tarde após o "reportABCEvent" ser chamado
describe("Alphabetic.ads", function() {
it("ABC events create an image request", function() {
var hook={};
spyOn(window, 'Image').andCallFake( function(x,y) {
hook={ src: {} }
return hook;
}
);
reportABCEvent('testa', 'testb', 'testc');
expect(hook.src).
toEqual('[zubzub]&arg1=testa&arg2=testb&event_value=testc');
});
Isso é para o jasmine 1.3, mas pode funcionar no 2.0 se "andCallFake" for alterado para o nome 2.0
Estou usando uma grade de kendo e, portanto, não posso alterar a implementação para um método getter, mas quero testar em torno disso (simulando a grade) e não testar a grade em si. Eu estava usando um objeto espião, mas ele não suporta simulação de propriedade, então faço o seguinte:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
É um pouco prolixo, mas funciona muito bem
Estou um pouco atrasado para a festa aqui eu sei, mas,
Você pode acessar diretamente o objeto de chamadas, que pode fornecer as variáveis para cada chamada
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
valueA
for umObservable
ouSubject
? Estou recebendoProperty valueA does not have access type get