Подтвердить что ты не робот

Как spyOn свойство value (а не метод) с Jasmine

Жасмин spyOn хорош для изменения поведения метода, но есть ли способ изменить свойство value (а не метод) для объекта? код может выглядеть следующим образом:

spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
4b9b3361

Ответ 1

В феврале 2017 года они объединили PR, добавив эту функцию, и выпустили в апреле 2017 года.

поэтому, чтобы шпионить за получателями/установщиками, которые вы используете: const spy = spyOnProperty(myObj, 'myGetterName', 'get'); где myObj - это ваш экземпляр, 'myGetterName' - это имя того, который определен в вашем классе как 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, где этот метод доступен, если вы заинтересованы.

https://github.com/jasmine/jasmine/blob/7f8f2b5e7a7af70d7f6b629331eb6fe0a7cb9279/src/core/requireInterface.js#L199

Отвечая на исходный вопрос, с Жасмин 2.6.1, вы бы:

const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();

Ответ 2

Жасмин не имеет такой функциональности, но вы можете взломать что-то вместе, используя Object.defineProperty.

Вы можете реорганизовать свой код, чтобы использовать функцию геттера, а затем шпионить за получателем.

spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);

Ответ 3

По какой-либо причине вы не можете просто изменить его прямо на объекте? Это не похоже на то, что javascript обеспечивает видимость свойства объекта.

Ответ 4

Лучший способ - использовать 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 объекта div.nativeElement.

Ответ 5

Если вы используете ES6 (Babel) или TypeScript, вы можете заглушить свойство, используя get и set accessors

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');

Ответ 6

Предположим, что существует такой метод, который требует тестирования Свойство 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');
    });

Это для жасмина 1.3, но может работать на 2.0, если "andCallFake" изменен на имя 2.0

Ответ 7

Я использую сетку кендо и, следовательно, не могу изменить реализацию на метод getter, но я хочу протестировать это (высмеивать сетку), а не тестировать саму сетку. Я использовал объект-шпион, но это не поддерживает свойство издевательств, поэтому я делаю это:

    this.$scope.ticketsGrid = { 
        showColumn: jasmine.createSpy('showColumn'),
        hideColumn: jasmine.createSpy('hideColumn'),
        select: jasmine.createSpy('select'),
        dataItem: jasmine.createSpy('dataItem'),
        _data: []
    } 

Он немного длинный, но он работает с удовольствием

Ответ 8

Я немного опаздываю на вечеринку, которую знаю, но

Вы можете напрямую обращаться к объекту вызовов, который может дать вам переменные для каждого вызова

expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)

Ответ 9

Правильный способ сделать это с помощью свойства spy on, это позволит вам смоделировать свойство объекта с определенным значением.

const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();

Ответ 10

Вы не можете смоделировать переменную, но вы можете создать для нее функцию getter и смоделировать этот метод в своем файле спецификации.