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

Шпионаж на конструктор с использованием жасмина

Я использую Jasmine для проверки того, созданы ли определенные объекты и на них вызывается метод.

У меня есть виджет jQuery, который создает объекты flipcounter и вызывает на них метод setValue. Код для flipcounter находится здесь: https://bitbucket.org/cnanney/apple-style-flip-counter/src/13fd00129a41/js/flipcounter.js

Флип-счетчики создаются с использованием:

var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});

Я хочу проверить, что создаются flipcounters, и на них вызывается метод setValue. Моя проблема заключается в том, как я могу следить за этими объектами еще до их создания? Я шпионить за конструктором и возвращать поддельные объекты? Пример кода действительно поможет. Спасибо за вашу помощь!:)

Update:

Я пробовал следить за flipCounter следующим образом:

myStub = jasmine.createSpy('myStub');
spyOn(window, 'flipCounter').andReturn(myStub);

//expectation
expect(window.flipCounter).toHaveBeenCalled();

Затем тестирование для вызова setValue с помощью flipCounter:

spyOn(myStub, 'setValue');

//expectation
expect(myStub.setValue).toHaveBeenCalled();

первый тест для инициализации flipCounter в порядке, но для тестирования вызова setValue все, что я получаю, это метод 'setValue() не существует'. Правильно ли я делаю это? Спасибо!

4b9b3361

Ответ 1

flipCounter - это еще одна функция, даже если она также создает объект. Следовательно, вы можете:

var cSpy = spyOn(window, 'flipCounter');

чтобы получить шпион на нем, и делать всевозможные проверки на нем или сказать:

var cSpy = spyOn(window, 'flipCounter').andCallThrough();
var counter = flipCounter('foo', options);
expect(cSpy).wasCalled();

Однако это кажется излишним. Этого было бы достаточно:

var myFlipCounter = new flipCounter("counter", options);
expect(myFlipCounter).toBeDefined();
expect(myFlipCounter.getValue(foo)).toEqual(bar);

Ответ 2

Я бы предложил использовать jasmine.createSpyObj(), когда вы хотите издеваться над объектами со свойствами, которые нужно отслеживать.

myStub = jasmine.createSpyObj('myStub', ['setValue']);
spyOn(window, 'flipCounter').andReturn(myStub);

Это проверяет взаимодействие с ожидаемым интерфейсом flipCounter, не зависящим от реализации flipCounter.

Ответ 3

Вам нужно реализовать поддельный конструктор для flipCounter, который устанавливает свойство setValue в функцию-шпион. Скажем, функция, которую вы хотите проверить, такова:

function flipIt() {
  var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
  myFlipCounter.setValue(100);
}

Ваша спецификация должна выглядеть так:

describe('flipIt', function () {
  var setValue;
  beforeEach(function () {
    setValue = jasmine.createSpy('setValue');
    spyOn(window, 'flipCounter').and.callFake(function () {
      this.setValue = setValue;
    });
    flipIt();
  });
  it('should call flipCounter constructor', function () {
    expect(window.flipCounter)
      .toHaveBeenCalledWith("counter", {inc: 23, pace: 500});
  });
  it('should call flipCounter.setValue', function () {
    expect(setValue).toHaveBeenCalledWith(100);
  });
});

Ответ 4

Следующее не зависит от "окна". Допустим, это код, который вы хотите проверить -

function startCountingFlips(flipCounter) {
    var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
}

Ваш тест может быть -

var initSpy = jasmine.createSpy('initFlipCounter');
var flipCounter = function(id, options) {
    initSpy(id, options);
}
startCountingFlips(flipCounter);
expect(initSpy).toHaveBeenCalledWith("counter", {inc:23, pace:500});

Ответ 5

Моя версия для проверки конструктора заключается в том, чтобы заглянуть в прототип:

spyOn(flipCounter.prototype, 'setValue').and.callThrough();
var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
expect(flipCounter.prototype.setValue).toHaveBeenCalledTimes(1);

Ответ 6

Не знаю, как это сделать, используя jasmine mocks, но если вам нужны мощные mocking/spy/stubs, я рекомендую sinon.js, который отлично работает с жасмином.

Из документов:

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

Mocks (и издевательские ожидания) - это поддельные методы (например, шпионы) с предварительно запрограммированное поведение (например, заглушки), а также запрограммированные ожидания. Макет провалит ваш тест, если он не используется как ожидается.

С помощью sinon.js вы можете создать макет конструктора flipCounter, который возвращает другой шпион.

Затем утверждаем, что конструктор вызывается с помощью constructorMock.calledWithNew() и утверждает, что возвращенный шпион вызывался с возвратом возвращаемого spy.calledWith(arg1, arg2...).