Ответы:
В феврале 2017 года они объединили PR, добавив эту функцию, выпущенную в апреле 2017 года.
так что, чтобы следить за геттерами / сеттерами, которые вы используете:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
где myObj - ваш экземпляр, myGetterName - это имя того, которое определено в вашем классе as, get myGetterName() {}
а третий параметр - это тип get
или set
.
Вы можете использовать те же утверждения, которые вы уже используете для шпионов, созданных с помощью spyOn
.
Так вы можете, например:
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.
Вот строка в исходном коде github, где этот метод доступен, если вам интересно.
Отвечая на исходный вопрос с помощью jasmine 2.6.1, вы должны:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
По какой причине вы не можете просто изменить это на объекте напрямую? Это не значит, что javascript обеспечивает видимость свойства объекта.
spyOn
явно указывает, что я хочу что-то имитировать, тогда как я напрямую устанавливаю свойство, неявно указывает, что я хочу что-то имитировать, и я не уверен, что кто-то еще поймет, что я издеваюсь над чем-то, когда он читает код. Другой случай заключается в том, что я не хочу изменять внутреннее поведение объекта, например, если я изменяю свойство length для массива, массив обрезается, так что макет будет лучше
spyOn
.
spyOn
не проходит тест, если свойство не существует.
TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
Жасмин не имеет такой функции, но вы можете что-то вместе взломать, используя Object.defineProperty
.
Вы можете реорганизовать свой код, чтобы использовать функцию получения, а затем шпионить за получателем.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
and.returnValue(1)
Лучше всего использовать spyOnProperty
. Он ожидает 3 параметра, и вам нужно передать get
или set
в качестве третьего параметра.
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);
Здесь я устанавливаю get
из clientWidth
из div.nativeElement
объекта.
Если вы используете ES6 (Babel) или TypeScript, вы можете заглушить свойство, используя методы доступа get и set.
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
Затем в своем тесте вы можете проверить, что свойство установлено с помощью:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
Правильный способ сделать это - использовать свойство spy on, это позволит вам смоделировать свойство объекта с определенным значением.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Предположим, существует такой метод, который требует тестирования. Необходимо проверить src
свойство крошечного изображения.
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 () заставляет «новое изображение» загружать поддельный код из теста, код spyOn возвращает объект, который имеет только свойство src
Поскольку область видимости переменной "hook" видна в поддельном коде в SpyOn, а также позже после вызова "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');
});
Это для jasmine 1.3, но может работать и на 2.0, если "andCallFake" заменить на имя 2.0.
Я использую сетку кендо и поэтому не могу изменить реализацию на метод получения, но я хочу протестировать это (имитируя сетку), а не тестировать саму сетку. Я использовал объект-шпион, но он не поддерживает насмешку над свойствами, поэтому я делаю следующее:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
Это немного затянуто, но работает приятно
Я немного опоздал на вечеринку, я знаю, но,
Вы можете напрямую получить доступ к объекту вызовов, который может предоставить вам переменные для каждого вызова
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
valueA
естьObservable
илиSubject
? Я получаюProperty valueA does not have access type get