Antworten:
Im Februar 2017 haben sie eine PR zusammengeführt und diese Funktion hinzugefügt, die sie im April 2017 veröffentlicht haben.
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
Um Getter / Setter auszuspionieren, die Sie verwenden:
Wenn myObj Ihre Instanz ist, ist 'myGetterName' der Name desjenigen, der in Ihrer Klasse als definiert ist, get myGetterName() {}
und der dritte Parameter ist der Typ get
oder set
.
Sie können dieselben Behauptungen verwenden, die Sie bereits für die mit erstellten Spione verwenden spyOn
.
So können Sie zum Beispiel:
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.
Hier ist die Zeile im Github-Quellcode, in der diese Methode verfügbar ist, wenn Sie interessiert sind.
Wenn Sie die ursprüngliche Frage mit Jasmin 2.6.1 beantworten, würden Sie:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Gibt es einen Grund, warum Sie es nicht einfach direkt am Objekt ändern können? Es ist nicht so, dass Javascript die Sichtbarkeit einer Eigenschaft für ein Objekt erzwingt.
spyOn
explizite Verwendung bedeutet, dass ich etwas verspotten möchte, während die Eigenschaft implizit festgelegt wird, dass ich etwas verspotten möchte, und ich bin nicht sicher, ob jemand anderes verstehen wird, dass ich etwas verspotte, wenn er den Code liest. Ein anderer Fall ist, dass ich das innere Verhalten des Objekts nicht ändern möchte. Wenn ich beispielsweise die Längeneigenschaft für ein Array ändere, wird das Array
spyOn
.
spyOn
den Test nicht, wenn die Eigenschaft nicht vorhanden ist.
TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
Jasmine hat diese Funktionalität nicht, aber Sie können möglicherweise etwas zusammen hacken Object.defineProperty
.
Sie können Ihren Code umgestalten, um eine Getter-Funktion zu verwenden, und dann den Getter ausspionieren.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
and.returnValue(1)
Der beste Weg ist zu verwenden spyOnProperty
. Es werden 3 Parameter erwartet und Sie müssen get
oder set
als dritten Parameter übergeben.
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);
Hier setze ich das get
of clientWidth
des div.nativeElement
Objekts.
Wenn Sie ES6 (Babel) oder TypeScript verwenden, können Sie die Eigenschaft mit get- und set-Accessoren löschen
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
Dann können Sie in Ihrem Test überprüfen, ob die Eigenschaft festgelegt ist mit:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
Der richtige Weg, dies zu tun, ist mit der Eigenschaft spy on, mit der Sie eine Eigenschaft für ein Objekt mit einem bestimmten Wert simulieren können.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Angenommen, es gibt eine Methode wie diese, die getestet werden muss. Die src
Eigenschaft des winzigen Bildes muss überprüft werden
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;
}
Das folgende spyOn () bewirkt, dass dem "neuen Bild" der gefälschte Code aus dem Test zugeführt wird. Der spyOn-Code gibt ein Objekt zurück, das nur eine src-Eigenschaft hat
Da die Variable "hook" im gefälschten Code im SpyOn und auch später nach dem Aufruf von "reportABCEvent" sichtbar sein soll
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');
});
Dies ist für Jasmin 1.3, funktioniert aber möglicherweise unter 2.0, wenn "andCallFake" in den Namen 2.0 geändert wird
Ich verwende ein Kendo-Raster und kann daher die Implementierung nicht in eine Getter-Methode ändern, aber ich möchte dies testen (das Raster verspotten) und nicht das Raster selbst testen. Ich habe ein Spionageobjekt verwendet, aber dies unterstützt keine Eigenschaftsverspottung. Deshalb mache ich Folgendes:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
Es ist ein bisschen langatmig, aber es funktioniert ein Vergnügen
Ich bin ein bisschen zu spät zur Party hier, ich weiß aber,
Sie können direkt auf das Aufrufobjekt zugreifen, das Ihnen die Variablen für jeden Aufruf gibt
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
valueA
einObservable
oder istSubject
? Ich bekommeProperty valueA does not have access type get