如何使用 Angular TestBed 将 Jasmine 间谍对象作为提供者传递

How to pass a Jasmine spy object as a provider using Angular TestBed

我想使用 Angular 的(版本 7)TestBed 来测试组件,并查看注入的服务是否有调用的方法。

观看这个 this tutorial,在 23:18 左右,他展示了如何创建茉莉花天空,因此您可以使用 toHaveBeenCalledTimes

等测试方法

我正在尝试做同样的事情,除了使用 TestBed 创建组件而不是像视频中那样手动实例化。

我有以下..

describe('AppComponent', () => {
    beforeEach(async(() => {
        
        fakeStartupService = jasmine.createSpyObj(fakeStartupService, ['start']);
        //fakeStartupService.start.and.returnValue(null);
                        
        TestBed.configureTestingModule({
            imports: [
                RouterTestingModule,
            ],
            providers: [
                ErrorHandler,
                { provide: StartupService, useValue: fakeStartupService },
            ],
            declarations: [
                AppComponent,        
            ],
                        
        }).compileComponents();     
    }));
    
    it('should have called start services start'), () => {
        expect(fakeStartupService.start).toHaveBeenCalledTimes(100);
    } 
});

第一个问题是,当我键入 expect(fakeStartupService. 时,我没有像视频中那样获得代码完成来显示 start 方法。

另一个(主要)问题是,虽然上面的编译和运行,我认为我没有正确,因为 expect(fakeStartupService.start).toHaveBeenCalledTimes(100); not 失败了 -该组件只调用它一次,但我断言了 100 次,所以它应该会失败。

我猜测在 { provide: StartupService, useValue: fakeStartupService }, 中使用 useValue,所以这可能是不正确的

我想知道:是否可以使用这样的间谍,如果可以,我该怎么做?

更新

实际上我有一个语法错误(描述后的括号)。

以下似乎对我有用。

it('should have called start services start once',  async () => {
  const fixture = TestBed.createComponent(AppComponent);    
  const app = fixture.debugElement.componentInstance;

  // As ngOnInit is async, use detectChanges and whenStable to wait for it to be finished.
  fixture.detectChanges();
  await fixture.whenStable()      
  expect(fakeStartupService.start).toHaveBeenCalledTimes(1);    
});

另外,等我异步ngOnInit我加了

 fixture.detectChanges();
 await fixture.whenStable()     

现在,唯一的小问题是他们如何在视频中获得 Intellisense。

我看了部分视频,不是intellisense/autocomplete。好吧,在某种程度上,它来自 Visual Studio 代码,而 IDE 匹配(并尽力)您输入的内容与之前在文档中输入的内容。我希望这是有道理的。

要在这种情况下获得真正的智能感知和自动完成功能,请在项目中某处创建一个名为 spied.ts 的接口,其定义如下:

export type Spied<T> = {
  [Method in keyof T]: jasmine.Spy;
};

然后当你定义fakeStartupService时,这样做:

import { Spied } from './where/spied/type/file/was/saved';
....
let fakeStartupService: Spied<StartupService>;

现在,当您键入 fakeStarupService.st 时,start 中的 autocomplete/intellisense 应该会出现。

我使用它并从这篇文章中得到它:https://pragmatic-coder.net/typesafe-jasmine-spies/。向下滚动到 The fix