Risposte:
Nel febbraio 2017, hanno unito un PR aggiungendo questa funzione, che hanno rilasciato nell'aprile 2017.
quindi per spiare i getter / setter usi:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
dove myObj è la tua istanza, 'myGetterName' è il nome di quello definito nella tua classe come get myGetterName() {}
e il terzo parametro è il tipo get
o set
.
Puoi usare le stesse affermazioni che usi già con le spie create con spyOn
.
Quindi puoi ad esempio:
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.
Ecco la riga nel codice sorgente di GitHub in cui questo metodo è disponibile se sei interessato.
Rispondendo alla domanda originale, con jasmine 2.6.1, potresti:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
C'è qualche motivo per cui non puoi cambiarlo direttamente sull'oggetto? Non è come se javascript imponga la visibilità di una proprietà su un oggetto.
spyOn
esplicitamente indica che voglio deridere qualcosa, mentre imposto direttamente la proprietà indica implicitamente che voglio deridere qualcosa e non sono sicuro che qualcun altro capirà che sto prendendo in giro qualcosa mentre legge il codice. Un altro caso è che non voglio cambiare il comportamento interno dell'oggetto, ad esempio se cambio la proprietà length per un array, l'array viene tagliato, quindi una simulazione sarà migliore
spyOn
.
spyOn
fallisce il test se la proprietà non esiste.
TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
Jasmine non ha questa funzionalità, ma potresti essere in grado di hackerare qualcosa insieme usando Object.defineProperty
.
Potresti effettuare il refactoring del codice per utilizzare una funzione getter, quindi spiare il getter.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
and.returnValue(1)
Il modo migliore è usare spyOnProperty
. Prevede 3 parametri e devi passare get
o set
come terzo parametro.
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);
Qui sto impostando il get
di clientWidth
di div.nativeElement
oggetto.
Se stai usando ES6 (Babel) o TypeScript puoi bloccare la proprietà usando le funzioni di accesso 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); }
}
Quindi nel tuo test puoi verificare che la proprietà sia impostata con:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
Il modo giusto per farlo è con la spia della proprietà, che ti permetterà di simulare una proprietà su un oggetto con un valore specifico.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Supponiamo che esista un metodo come questo che necessita di test. La src
proprietà dell'immagine minuscola deve essere verificata
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;
}
SpyOn () di seguito fa sì che la "nuova immagine" riceva il codice falso dal test il codice spyOn restituisce un oggetto che ha solo una proprietà src
Poiché la variabile "hook" ha l'ambito per essere visibile nel codice falso in SpyOn e anche successivamente dopo che viene chiamato "reportABCEvent"
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');
});
Questo è per jasmine 1.3 ma potrebbe funzionare su 2.0 se "andCallFake" viene modificato nel nome 2.0
Sto usando una griglia di kendo e quindi non posso cambiare l'implementazione in un metodo getter, ma voglio testare questo (deridendo la griglia) e non testare la griglia stessa. Stavo usando un oggetto spia ma questo non supporta la derisione delle proprietà, quindi lo faccio:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
È un po 'prolisso ma funziona a meraviglia
Sono un po 'in ritardo per la festa qui lo so ma,
Puoi accedere direttamente all'oggetto chiamate, che può darti le variabili per ogni chiamata
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
valueA
è unObservable
oSubject
? Sto ottenendoProperty valueA does not have access type get