Working 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 将是一个空 spy,即它仅用于跟踪函数被调用的次数、使用的参数等。但它不会使用原始实现,这不是您想要的,因为您还有与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 并在其中放置一些断点以获得更流畅的调试体验。