Жасмин - следите за вызовом метода в конструкторе - PullRequest
60 голосов
/ 05 января 2012

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

Объект:

Klass = function() {
    this.called_method();
};

Klass.prototype.called_method = function() {
  //method to be called in the constructor.
}

Я хочу сделать что-то подобное в спецификации:

it('should spy on a method call within the constructor', function() {
    spyOn(window, 'Klass');
    var obj = new Klass();
    expect(window.Klass.called_method).toHaveBeenCalled();
});

Ответы [ 2 ]

104 голосов
/ 05 января 2012

Шпион прямо по способу-прототипу:

describe("The Klass constructor", function() {
  it("should call its prototype's called_method", function() {
      spyOn(Klass.prototype, 'called_method');  //.andCallThrough();
      var k = new Klass();
      expect(Klass.prototype.called_method).toHaveBeenCalled();
  });
});
11 голосов
/ 19 ноября 2013

В целом, я согласен с ответом Дэйва Ньютона выше.Тем не менее, есть некоторые крайние случаи для этого подхода, которые вы должны рассмотреть.

Возьмите вариант решения Дейва с другим тестовым примером:

// production code
var Klass = function() {
  this.call_count = 0;
  this.called_method();
};
Klass.prototype.called_method = function() {
  ++this.call_count;
};

// test code
describe("The Klass constructor", function() {
  it("should call its prototype's called_method", function() {
    spyOn(Klass.prototype, 'called_method');
    var k = new Klass();
    expect(k.called_method).toHaveBeenCalled();
  });
  it('some other test', function() {
    var k = new Klass();
    expect(k.call_count).toEqual(1);
  });
});

Второй тест не пройден, потому чтонастройка шпиона в первом тесте сохраняется через границы теста во втором методе;call_method не увеличивает call_count, поэтому this.call_count не равно 1. Также возможно придумать сценарии с ложными срабатываниями - тесты, которые проходят, которые не должны.

Кроме того, потому чтошпион остается, чем больше экземпляров Klass создано, тем больше будет куча памяти, которую будет использовать шпион, потому что шпион будет записывать каждый вызов call_method.Это, вероятно, не проблема в большинстве случаев, но вы должны знать об этом, на всякий случай.

Простым решением этой проблемы было бы убедиться, что шпион удален после того, как он был использован,Это может выглядеть немного некрасиво, но что-то вроде этого работает:

// test code
describe("The Klass constructor", function() {
  it("should call its prototype's called_method", function() {
    var spy = jasmine.createSpy('called_method');
    var method = Klass.prototype.called_method;
    Klass.prototype.called_method = spy;
    var k = new Klass();
    expect(spy).toHaveBeenCalled();
    Klass.prototype.called_method = method;
  });

[ПРИМЕЧАНИЕ - небольшое мнение, чтобы закончить] Лучшим решением было бы изменить способ написания рабочего кода, чтобы сделать код легчетестовое задание.Как правило, слежка за прототипами - это, вероятно, кодовый запах, которого следует избегать.Вместо того, чтобы создавать зависимости в конструкторе, вставьте их.Вместо инициализации в конструкторе, обратитесь к соответствующему методу init.

...