Angular 如何监视角度测试规范中ngOnInit内部订阅中调用的方法?

Angular 如何监视角度测试规范中ngOnInit内部订阅中调用的方法?,angular,unit-testing,asynchronous,spy,Angular,Unit Testing,Asynchronous,Spy,我需要测试是否根据属性值正确初始化了字段。此属性用于在ngOnInit中调用的订阅下调用的方法中的条件。我正在使用spy返回一个布尔值作为此规范的模拟值。问题是调用和spyOn操作之间存在延迟,即使spy更改了属性的值,似乎速度不够快 组件技术 //Value I want to test value; //This is the property I need to check get isThisTrue() { return this.externalService.isTrue

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

组件技术

//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;
}
组件规范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);
}))

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

我面临类似的问题,spyOn方法返回的数据没有用于组件的ngOnInit

在我的例子中,问题是组件是在beforeach()方法中创建的

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

我将代码从beforeach()方法移动到函数createComponent()中

并在使用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内的订阅中返回一个值。您需要以异步方式执行它,然后调用完成,或者在具有异步行为的测试中使用任何其他方法。我尝试过@Nanotron,但问题是该方法是在订阅中调用的。通常,异步方法在您希望等待直到收到满足信息时会有所帮助,这样您就可以使用它了。我不关心订阅的内容,我只关心内部调用的方法。即使在我使用异步方法时,spy也不起作用。您可能也需要对其进行模拟/监视。例如,如果该订阅使用http req,则需要模拟该订阅。你的方法永远不会被调用。你调试过吗?在ngOnit中放置一个断点,看看发生了什么。这个答案帮助我了解了我的情况:我试图窥探一个组件的方法,该方法在ngOnInit中调用。我使用的是相同的设置,组件是在beforeach中创建的,因此在我有机会对其进行监视之前调用了该方法。我也在使用ComponentFixtureAutoDetect,所以当我在测试中移动组件创建(以绕过自动更改检测)时,它仍然不起作用,因为更改检测仍在组件创建时运行。我不得不对CFAD进行注释,并进行手动更改检测,以使其最终工作。
function createComponent(){
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
 }
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