Рабочий StackBlitz.
Было несколько опечаток:
Во-первых, я думаю, вы хотели объявить getAnotherReport
как значение, а не как тип:
let getAnotherReport = {
text: null,
ref: "7478B45D4D4F1400223BD2F1",
num: 19,
urn: "123",
title: "Test report",
label: "accept & view"
};
затем в SearchComponent.viewFunc
у вас есть url = 'main'
и в вашей спецификации у вас есть:
expect(routerSpy.navigate).toHaveBeenCalledWith(["/main"], {
queryParams: { queryString: queryString }
});
и должно быть без /
:
expect(routerSpy.navigate).toHaveBeenCalledWith(["main"], {
queryParams: { queryString: queryString }
});
А теперь давайте посмотрим самое интересное.
Сначала мы рассмотрим первое утверждение:
const mySpy = jasmine.createSpy("getAnotherReport").and.callThrough();
/* ... */
testee.viewFunc(queryString);
/* .... */
expect(mySpy).toHaveBeenCalled();
проблема здесь связана с тем, как вы решили шпионить за viewFunc
. В этом случае вы использовали spyOn(component, "viewFunc");
: это соответствующие биты, которые происходят под капотом, когда вы вызываете spyOn
:
var originalMethod = obj[methodName],
spiedMethod = createSpy(methodName, originalMethod),
где createSpy
будет пустым шпионом, т.е. он будет просто использоваться для отслеживания того, сколько раз была вызвана функция, с какими аргументами и т. д. Но он не будет использовать исходную реализацию, а это не то, что вам нужно, потому что у вас также есть утверждения, касающиеся ReportService
, которые находятся в исходной реализации viewFunc
.
Чтобы использовать первоначальную реализацию, вы можете использовать .and.callThrough()
:
// a quick look at the fact that it uses the original function
SpyStrategy.prototype.callThrough = function() {
this.plan = this.originalFn;
return this.getSpy();
};
reportService = TestBed.get(ReportService);
// and here we are using it
spyOn(component, "viewFunc").and.callThrough();
поставить все это вместе:
// you can get ahold of the current spy like this
const mySpy = mockReportService.getAnotherReport.and.returnValue(
of(getAnotherReport)
);
expect(testee).toBeTruthy();
testee.viewFunc(queryString);
expect(mySpy).toHaveBeenCalled();
А теперь ко второму утверждению:
// inside providers array
{ provide: Router, useValue: routerSpy },
/* ... */
const routerSpy = { navigate: jasmine.createSpy("navigate") };
expect(routerSpy.navigate).toHaveBeenCalledWith(["main"], {
queryParams: { queryString: queryString }
});
В этом случае обратите внимание, что вы используете объект отличный от того, с которым вы издевались над классом Router
.
Вам придется использовать тот же объект, который вы использовали для издевательства над рассматриваемым классом, поэтому способ решения этой проблемы будет следующим:
let routerSpy = { navigate: jasmine.createSpy("navigate") };
/* ... */
// inside providers array
{ provide: Router, useValue: routerSpy },
/* ... */
const mySpy = mockReportService.getAnotherReport.and.returnValue(
of(getAnotherReport)
);
expect(testee).toBeTruthy();
testee.viewFunc(queryString);
expect(mySpy).toHaveBeenCalled();
expect(routerSpy.navigate).toHaveBeenCalledWith(["main"], {
queryParams: { queryString: queryString }
});
Быстрая подсказка
Я тоже не очень хорошо знаком с Jasmine, но мне очень помогло увидеть, что он делает под капотом. Не вникая в каждую мельчайшую деталь, вы можете, по крайней мере, получить интуитивное представление о том, как решить свою проблему. Итак, в приложении StackBlitz, подобном тому, которое вы указали, вы можете:
- открыть инструменты разработчика
- нажмите
CTRL + P
и введите jasmine.js
(может быть более одного файла, правильный - это тот, в котором находятся известные методы, такие как callThrough
- вы можете проверить это, нажав CTRL + SHIFT + O
и введя имя метода)
кроме того, вы можете искать search.component.ts
и размещать там несколько точек останова для более плавной отладки.
person
Andrei Gătej
schedule
21.02.2021