Как использовать шпионы Jasmine для объекта, созданного внутри другого метода?
Учитывая следующий фрагмент кода, как бы вы создали тест Jasmine spyOn
, чтобы подтвердить, что doSomething
вызывается, когда вы запустите MyFunction
?
function MyFunction() {
var foo = new MyCoolObject();
foo.doSomething();
};
Вот как выглядит мой тест. К сожалению, я получаю сообщение об ошибке, когда вычисляется вызов spyOn
:
describe("MyFunction", function () {
it("calls doSomething", function () {
spyOn(MyCoolObject, "doSomething");
MyFunction();
expect(MyCoolObject.doSomething).toHaveBeenCalled();
});
});
Жасмин, по-видимому, не распознает метод doSomething
в этой точке. Любые предложения?
Ответы
Ответ 1
Когда вы вызываете new MyCoolObject()
, вы вызываете функцию MyCoolObject
и получаете новый объект с соответствующим прототипом. Это означает, что при spyOn(MyCoolObject, "doSomething")
вы не настраиваете шпиона на объект, возвращаемый вызовом new
, а на возможную функцию doSomething
в самой функции MyCoolObject
.
Вы должны иметь возможность сделать что-то вроде:
it("calls doSomething", function() {
var originalConstructor = MyCoolObject,
spiedObj;
spyOn(window, 'MyCoolObject').and.callFake(function() {
spiedObj = new originalConstructor();
spyOn(spiedObj, 'doSomething');
return spiedObj;
});
MyFunction();
expect(spiedObj.doSomething).toHaveBeenCalled();
});
Ответ 2
В качестве альтернативы, как намекал Грегг, мы могли бы работать с 'prototype'. То есть, вместо того, чтобы напрямую следить за MyCoolObject, мы можем отслеживать MyCoolObject.prototype.
describe("MyFunction", function () {
it("calls doSomething", function () {
spyOn(MyCoolObject.prototype, "doSomething");
MyFunction();
expect(MyCoolObject.prototype.doSomething).toHaveBeenCalled();
});
});