【问题标题】:SpyOn in Angular testingAngular 测试中的 SpyOn
【发布时间】:2018-04-11 12:41:46
【问题描述】:

首先,我很抱歉。我真的是 Angular 的新手,我不确定我知道的足够多,无法提出一个好的问题,更不用说提供一些小的工作示例了。

我正在尝试在单元测试中使用 spyOn,但运气不佳。

基本上,我的单​​元测试调用组件上的一个方法,该方法调用一个 service1,该方法调用另一个 service2。

当我尝试监视 service1 时,它没有使用我提供的模拟值。它调用“真正的”ServiceProvidersHTTPService.getAllUsers 并使用 AppConfigService 而不是 MockAppConfigService。

我将从复制我的测试开始。

describe('ProjectAnalystComponent', () => {
  let component: ProjectAnalystComponent;
let fixture: ComponentFixture<ProjectAnalystComponent>;
let service: ServiceProvidersHTTPService ;

  beforeEach(async(() => {
TestBed.configureTestingModule({
  imports: [HttpClientModule, RouterTestingModule],
    declarations: [ ProjectAnalystComponent ],
  providers: 
  [
    ServiceProvidersHTTPService, 
    CurrentCreateProjectService, 
    NotificationService, 
    MessageService,
    ProjectLeadAnalystHTTPService,
      ExceptionService,
      {provide: AppConfigService, useClass: MockAppConfigService }

  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
})
.compileComponents();
  }));

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

it('should create', () => {
    console.log("######### Did this run");
    let service = fixture.debugElement.injector.get(ServiceProvidersHTTPService);
    spyOn(service, 'getAllUsers').and.returnValue('{}');

    expect(component).toBeTruthy();
  });
});

【问题讨论】:

    标签: angular unit-testing typescript


    【解决方案1】:

    TL;DR模拟你的服务。

    说明

    在您的测试平台中,您提供实际服务:

    providers:[ServiceProvidersHTTPService, ...
    

    这意味着您实际上调用了服务的真实方法

    如果你模拟你的服务,就像你在那里做的那样:

    {provide: AppConfigService, useClass: MockAppConfigService }
    

    然后您调用在您的模拟中声明的随机函数

    模拟的另一个好处,你摆脱了依赖的依赖。

    正如您所说,您的服务调用另一个服务:如果您模拟您的第一个服务,您不必将此服务的依赖项添加到您的测试平台中

    所以,他们还有很长的路要走:

    const mock = {
      provide: ServiceProvidersHTTPService,
      useValue: {
        getAllUsers: () => null
      }
    };
    

    现在在您的测试平台中:

    providers: [mock, ...
    

    useValue中,你必须把你实际服务的所有变量和所有函数,并mock它们

    在这种情况下,您的函数 getAllUsers 将简单地返回 null,而不是进行 HTTP 调用。你可以让它返回你想要的任何东西(好的做法是返回一个与应该返回的值相同类型的值)。

    最后一条建议:你的单元测试应该只测试你的实际功能的功能和方法(这里是ProjectAnalystComponent)。您不应该在此处测试您的服务是否调用其他服务:您应该在您的服务的单元测试中进行测试

    如果您有任何问题,请随时提问!

    【讨论】:

    • 绝对同意你的最后一点.. 处理别人的测试.. 他们肯定比单元测试更“集成”测试。这解决了我的直接问题,但现在其他问题失败了。我想我需要一个 partialMock。
    • 对我来说这看起来像是单元测试!但是,如果您有其他问题,请不要犹豫,提出另一个问题,甚至编辑这个问题(如果有,请通知我)
    • 只是为了澄清......所以如果我提供服务1,并提供{service2,useClass:mockservice2},那么service1调用service2;但它不尊重测试平台提供?
    • 如果您的组件ProjectAnalystComponent 在其构造函数中没有第二个服务(作为依赖项),那么您甚至不必提供它。这就是为什么嘲笑很重要。您的组件是使用服务 2,还是您的组件通过服务 1 使用服务 2?
    • 组件通过service1使用service1。您的示例解决了我的问题.. 但是 getAllUsers 返回的结果是一个 Observable.. 所以我必须创建一个 observable 来返回,而不仅仅是 null。非常感谢您的帮助@trichetriche 这真的让我很沮丧。
    猜你喜欢
    • 2020-12-16
    • 2017-09-15
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2019-07-11
    • 2020-11-14
    • 1970-01-01
    • 2020-04-10
    相关资源
    最近更新 更多