【问题标题】:Jasmine test angular component with private property具有私有属性的茉莉花测试角组件
【发布时间】:2019-01-22 22:55:25
【问题描述】:

我有这个代码。我将myData 保存在ngOnInit 中。当我通过单击按钮测试 myMethod 时,this.myData 在 myMethod 中为 undefined。

@Component({
   templateUrl: ''
})

export class MyComponent implements OnInit {
   myData: MyClass;
   constructor() {}
   ngOnInit() {
      this.myData = // some code
   }

   myMethod() {
    this.myData is undefined here
   }
}

我的规范文件是:

describe('MyComponent', () => {

 // set up stubs 
 beforeEach(async(() => {
 TestBed.configureTestingModule({
  declarations: [  MyComponent ],
  providers:    [
  ],
  imports: [
   FormContainer
  ],
  schemas: [NO_ERRORS_SCHEMA],
})
.compileComponents();

  fixture = TestBed.createComponent(MyComponent);
  comp = fixture.debugElement.componentInstance;
 }));

  it('should call myMethod', fakeAsync(() => {
    element.querySelectorAll('button')[0].click();
    fixture.detectChanges();
    fixture.whenStable().then(async() => {
      fixture.detectChanges();
    });
  }));
});

【问题讨论】:

  • 您是否将 myData 设置为 MyClass 属性?
  • @codeepic 是的,我已经更新了问题,程序编译正常。

标签: angular jasmine components


【解决方案1】:

这是因为您在按钮存在之前查询它。只需将您的fixture.detectChanges() 移动到您的element.querySelectorAll() 之前,它应该可以工作。有关原因的详细信息,请参阅Angular Docs。

it('should call myMethod', fakeAsync(() => {
    spyOn(comp, 'myMethod').and.callThrough();
    fixture.detectChanges(); // <--- Move to here from below ...
    element.querySelectorAll('button')[0].click();
    // fixture.detectChanges();  <-- Move this ...
    expect(comp.myMethod).toHaveBeenCalled();
    // fixture.whenStable().then(async(() => {
    //   fixture.detectChanges();
    // }));
}));

工作StackBlitz。查看控制台,我修改myMethod()如下:

myMethod() {
  console.log(this.myData); // is no longer undefined here
}

我希望这会有所帮助。

更新

我已修改 StackBlitz 以使其更清晰。以下是 StackBlitz 中的新测试:

it('comp.myData should be undefined if element.query is first', () => {
    element.querySelectorAll('button')[0].click();
    expect(comp.myData).toBeUndefined(); // <-- Note this is UNDEFINED at this point
    fixture.detectChanges(); // <--- This is in the wrong place ...
});

it('comp.myData should be defined if fixture.detectChanges() is first', () => {
    fixture.detectChanges(); // <--- Now this is in the before the query.
    element.querySelectorAll('button')[0].click();
    expect(comp.myData).toEqual({data: 'test'}); // <-- Note this is now defined
});

如果您查看 console.log,您将看到以下内容:

Console was cleared
undefined

{data: "test"}

第一个未定义来自第一个测试,当时fixture.detectChanges() 出现在错误的位置。第二个{data: "test"} 来自现在定义的第二个测试。

我希望这会有所帮助。

【讨论】:

  • 我把它移到下面了,它仍然有效:stackoverflow-q-54317647-yfuuga.stackblitz.io
  • 测试仍然通过,是的(我可能应该对此更清楚) - 但在 console.log() 中,如果fixture.detectChanges(),你会看到this.myData 是undefined在element.querySelectorAll() 之后
  • 我仍然在控制台中看到 {data: "test"} :stackblitz.com/edit/…
  • 实际上,如果您在上一条评论中发送的链接中打开控制台,您会看到它显示“未定义”。无论如何,我已经更新了我上面的答案,希望能让这个问题变得清晰。 :)
  • 它现在可以工作了,没想到我要工作测试而不是点击按钮。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多