Angular 使用 mockedService 进行测试不会 return 模拟数据

Angular Test with mockedService doesn't return the mocked Data

显然,我仍然缺少理解模拟服务的重要内容,我很乐意提供一些信息。

我想在我的组件中测试的代码是:

modulesToDisplay: any[] = [];

...

getModules() {
  this.configService.getModulesToDisplay().subscribe(modules => {
    this.modulesToDisplay = modules;
    }
  );
}

我想测试当我从服务中获取内容时是否重新分配了 modulesToDisplay。所以在我的测试文件中,我创建了一个 serviceMock,其中 returns 一个包含两个项目的数组

let configServiceMock: any;

...

beforeEach(async(() => {
  configServiceMock = jasmine.createSpyObj('ConfigService', ['getModulesToDisplay']);
  configServiceMock.getModulesToDisplay.and.returnValue( of(['firstmodule', 'secondmodule']) );

  ...

providers: [
        { ConfigService, useValue: configServiceMock }
      ]
    }).compileComponents();

  beforeEach(() => {
    fixture = TestBed.createComponent(SomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

    it('should assign result to modulesToDisplay', () => {
    component.getModules();
    expect(component.modulesToDisplay.length).toBeGreaterThan(0);
  });
...

我预计这个测试会通过,因为我认为在我的测试中调用 'component.getModules();' 会使用模拟数据。但它没有, modulesToDisplay 仍然是我在组件中初始化的空数组。所以我想我还是没有理解mocking数据的正确原理。

即使 of 应该发出你的模拟值,我怀疑你可能仍然需要在异步上下文中执行它。如果您将规格更改为:

会发生什么
it('should assign result to modulesToDisplay', fakeAsync(() => {
  component.getModules();
  flushMicrotasks();
  fixture.detectChanges();
  expect(component.modulesToDisplay.length).toBeGreaterThan(0);
}));

通常当我的模拟似乎没有被使用时,这与我提供给配置的模拟对象与提供给 TestBed.configureTestingModule 的对象不匹配有关。

我尝试过两种方法来解决这个问题。

1.) 不再使用 useValue 构建提供程序,而是像这样切换到 useFactory

...
providers: [{ provide: ConfigService, useFactory: () => configServiceMock }]

2.) 另一种方法是在配置后获取服务进行测试,如下所示:

const csMock = jasmine.createSpyObject('ConfigureService', [...]);

TestBed.configureTestingModule(
...
providers: [{ provide: ConfigureService, useValue: csMock }]
);
configServiceMock = TestBed.get(ConfigureService);

模拟非常简单。让我帮你:


beforeEach(async(() => {
  ...

  providers: [
        { ConfigService, useClass: MockConfigService}
      ]
    }).compileComponents();

  beforeEach(() => {
    fixture = TestBed.createComponent(SomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should assign result to modulesToDisplay', () => {
    component.getModules();
    expect(component.modulesToDisplay.length).toBeGreaterThan(0);
  });



模拟class

export class MockConfigService{
   getModulesToDisplay(){
     return of({
         // whatever module object structure is
     })
   }
}

这会很有效。我强烈建议您 this article which has a real world example to test a component. For the basics, this article would be helpful