Odpowiedzi:
W lutym 2017 roku połączyli PR dodając tę funkcję, wydali w kwietniu 2017.
więc aby szpiegować getters / setters, których używasz:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
gdzie myObj jest twoją instancją, 'myGetterName' to nazwa tego zdefiniowanego w twojej klasie as, get myGetterName() {}
a trzeci parametr to typ get
lub set
.
Możesz użyć tych samych twierdzeń, których już używasz w przypadku szpiegów utworzonych w programie spyOn
.
Możesz więc na przykład:
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.
Oto wiersz w kodzie źródłowym github, w którym ta metoda jest dostępna, jeśli jesteś zainteresowany.
Odpowiadając na pierwotne pytanie, z jaśminem 2.6.1:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Jest jakiś powód, dla którego nie możesz po prostu zmienić tego bezpośrednio na obiekcie? To nie jest tak, że javascript wymusza widoczność właściwości na obiekcie.
spyOn
jawnie wskazuje, że chcę coś mockować, podczas gdy ja bezpośrednio ustawiam właściwość niejawnie wskazuje, że chcę coś mock, i nie jestem pewien, czy ktoś inny zrozumie, że kpię z czegoś, gdy czyta kod. Innym przypadkiem jest to, że nie chcę zmieniać wewnętrznego zachowania obiektu, na przykład jeśli zmienię właściwość length dla tablicy, tablica jest przycinana, więc makieta będzie lepsza
spyOn
.
spyOn
nie zdaje testu, jeśli nieruchomość nie istnieje.
TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
Jasmine nie ma takiej funkcji, ale możesz zhakować coś razem za pomocą Object.defineProperty
.
Możesz refaktoryzować swój kod, aby użyć funkcji getter, a następnie szpiegować getter.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
and.returnValue(1)
Najlepszym sposobem jest użycie spyOnProperty
. Oczekuje 3 parametrów i musisz przekazać get
lub set
jako trzeci parametr.
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);
Ja tu ustawienie get
od clientWidth
od div.nativeElement
obiektu.
Jeśli używasz ES6 (Babel) lub TypeScript, możesz usunąć właściwość za pomocą metod dostępu get i set
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
Następnie w swoim teście możesz sprawdzić, czy właściwość jest ustawiona za pomocą:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
Właściwym sposobem na to jest szpiegowanie właściwości, co pozwoli na zasymulowanie właściwości obiektu o określonej wartości.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Załóżmy, że istnieje metoda podobna do tej, która wymaga przetestowania. src
Właściwość małego obrazu wymaga sprawdzenia
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;
}
Poniższa funkcja spyOn () powoduje podanie "nowego obrazu" fałszywego kodu z testu kod spyOn zwraca obiekt, który ma tylko właściwość src
Ponieważ zmienna "hook" jest widoczna w fałszywym kodzie w SpyOn, a także później po wywołaniu "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');
});
To jest dla jaśminu 1.3, ale może działać na 2.0, jeśli "andCallFake" zostanie zmieniona na nazwę 2.0
Używam siatki kendo i dlatego nie mogę zmienić implementacji na metodę pobierającą, ale chcę testować wokół tego (mockowanie siatki), a nie testować samej siatki. Używałem obiektu szpiegowskiego, ale to nie obsługuje mockowania właściwości, więc robię to:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
Jest trochę rozwlekły, ale działa świetnie
Jestem trochę spóźniony na imprezę, którą znam, ale
Możesz uzyskać bezpośredni dostęp do obiektu wywołań, który może dostarczyć zmienne dla każdego wywołania
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
valueA
jestObservable
lubSubject
? DostajęProperty valueA does not have access type get