【问题标题】:How to spy on a method called in a subscription inside ngOnInit in Angular test spec?如何监视Angular测试规范中ngOnInit内订阅中调用的方法?
【发布时间】:2019-06-15 07:52:52
【问题描述】:

我需要测试我是否根据属性值正确初始化了我的字段。此属性用于在 ngOnInit 中调用的订阅下调用的方法内的条件中。我正在使用间谍返回一个布尔值作为该规范的模拟值。问题是调用和 spyOn 操作之间存在延迟,即使 spy 更改了属性的值,也似乎不够快。

组件.ts

//Value I want to test
value;

//This is the property I need to check
get isThisTrue() {
    return this.externalService.isTrue();
}

ngOnInit() {
this.otherService.getSomething().subscribe(res => {
  this.method();
   })
}

method() {
  if(this.isThisTrue) {
   this.value = 1;
  } else {
     this.value = 2;
}

component.spec.ts

//That is my failing test.
it('should be 2', inject([ExternalService], (service) => {
  spyOn(service, 'isTrue').and.returnValue(false);
  component.ngOnInit();
  fixture.detectChanges();
  expect(value).toBe(2);
}))

ps.:如果我在组件内部强制结果为 false,则测试通过。

【问题讨论】:

  • 我只想监视一个方法调用并在 ngOnInit 内的订阅中返回一个值。
  • 您需要异步执行它并调用 done 或使用任何其他方法进行您有异步行为的测试。
  • 我已经尝试过@Nanotron,但问题是在订阅中调用了该方法。通常,当您想要等待直到收到履行时,异步方法会有所帮助,以便您可以使用它。我不关心订阅了什么,我只关心里面调用的方法。即使我使用异步方法,间谍也无法工作
  • 你可能还需要模拟/监视它。例如,如果该订阅使用的是 http req,则需要对其进行模拟。你的方法永远不会被调用。你有没有调试过它?在 ngOnit 中放一个断点,看看会发生什么

标签: angular unit-testing asynchronous spy


【解决方案1】:

我遇到了类似的问题,即 spyOn 方法返回的数据没有在组件的 ngOnInit 中使用。

我的问题是组件是在 beforeEach() 方法中创建的

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

因此,它的 ngOnInit() 也会在 spy 方法返回模拟数据之前立即被调用。

我将代码从 beforeEach() 方法移到了函数 createComponent()

function createComponent(){
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
 }

并在使用 spyOn 返回模拟数据后从测试规范中调用此函数。

it('should create component with 2 rows', async () => {
    const expectedData: string[] = ['row 1', 'row 2'];
    myServiceSpy.getData.and.returnValue(expectedData));

    createComponent();

    expect(component).toBeTruthy();
    fixture.whenStable().then(() => {
        expect(myServiceSpy.getData).toHaveBeenCalled();
        expect(component.data.length).toEqual(2);
    });
});

Now, the component is getting the mock data as expected

【讨论】:

  • 这个答案帮助我弄清楚了我的情况:我试图监视一个组件的方法,该方法在 ngOnInit 中调用。我使用的是相同的设置,组件是在 beforeEach 中创建的,因此在我有机会在其上放置间谍之前调用了该方法。我也在使用 ComponentFixtureAutoDetect,所以当我在测试中移动组件创建(绕过自动更改检测)时,它仍然不起作用,因为更改检测仍在组件创建时运行。我必须评论 CFAD 并进行手动更改检测才能使其最终工作。
猜你喜欢
  • 1970-01-01
  • 2020-02-12
  • 2020-08-17
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 2019-04-16
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多