Angular Jasmine 间谍未被调用

Angular Jasmine spy not being called

我正在按照官方 Angular 教程测试调用异步服务函数的组件:https://angular.io/guide/testing#component-with-async-service

创建间谍:

const gardenSpy = jasmine.createSpyObj('GardenService', ['getGardens', 'createGarden']);
gardenSpy.getGardens.and.returnValue(of(testGardens));
...
gardenServiceSpy = TestBed.get(GardenService);

将 TestBed 配置为使用我的间谍而不是实际服务:

TestBed.configureTestingModule({
  declarations: [ MyGardensComponent ],
  providers: [
    { provide: GardenService, useValue: gardenSpy }
  ],
  imports: [FormsModule, HttpClientTestingModule]
})
.compileComponents();

然后,失败的单元测试:

it('should load the gardens', () => {
  fixture.detectChanges();
  component.getGardens();

  expect(gardenServiceSpy.getGardens.calls.any()).toBe(true, 'getGardens called');
});

正如您在此处的覆盖率报告中所见,subscribe 方法从未被执行,间谍断言失败。

coverage report

根据 Angular 教程,此方法应该有效并允许我同步 return observable。手动调用间谍方法可以正常工作并且 returns 正确,所以我假设间谍服务的注入存在问题,而不是间谍本身的创建。如有任何帮助,我们将不胜感激!

如果你需要查看整个文件,我做了一个 plunker here(实际上不是 运行,只是为了查看文件)

感谢您在 Plunker 中提供所有代码。我实际上将它移到了 Stackblitz,这样我就可以准确地看到你所看到的并观看它 运行。我不得不对服务进行 stub,但这无关紧要,因为无论如何你都要用间谍替换它。

我通过在 @Component 部分的 my-gardens.component.ts 文件中注释掉 providers 行来让它工作:

@Component({
  selector: 'app-my-gardens',
  templateUrl: './my-gardens.component.html',
  styleUrls: ['./my-gardens.component.css'],
  // providers: [GardenService, NgbModal]
})

这有效地覆盖了原始服务的间谍。您将供应商行放在那里而不是 module.ts 中有什么原因吗?

正如您在 Stackblitz 中看到的那样,测试正在通过并且正在调用订阅代码(检查控制台日志)。