角度测试:订阅组件构造函数内部的服务是未定义的



有一个服务在组件的构造函数中订阅。在编写测试用例时,它给出了未定义的 this.data。

我试过使用间谍和模拟

  export class MyComponent {
  private data;
  constructor(private myservice:MyService) {
      this.myService.currentMessage.subscribe((message) => this.data = message);
   if(this.data) {
     let response = true;
  } else {
     let response = false;
}

服务网

  @Injectable()
  export class MyService {
    private messageSource = new BehaviorSubject<string>("");
    public currentMessage = this.messageSource.asObservable();
    constructor() { }
     changeMessage(message: string) {
     this.messageSource.next(message);
  }
 }

测试用例

    describe('MyComponent', () => {
    let component: MyComponent;
    let fixture: ComponentFixture<MyComponent>;
    let data:string = 'mystring';
    beforeEach(async(() => {
         const dataServiceStub = { currentMessage: { subscribe: () => ({}) } };
    TestBed.configureTestingModule({
      schemas: [NO_ERRORS_SCHEMA],
      declarations: [MyComponent],
      providers: [
    { provide: MyService, useValue: dataServiceStub }],
    }).compileComponents();
   }));
   beforeEach(() => {
         fixture = TestBed.createComponent(MyComponent);
         component = fixture.componentInstance;
         let service = fixture.debugElement.injector.get(MyService);
         service.currentMessage = Observable.of(data);
        //spyOn(service, 'currentMessage').and.returnValue(data);
   });
   it('can load instance', () => {
        expect(component).toBeTruthy();
   });
 });

除非我缺少某些内容,否则问题是因为您的构造函数在您更改服务的可观察性之前就已完成。

 fixture = TestBed.createComponent(MyComponent); // The MyComponent constructor runs here
 component = fixture.componentInstance;
 let service = fixture.debugElement.injector.get(MyService);
 service.currentMessage = Observable.of(data); // The Observable is changed here.

要解决此问题,我认为您需要更改可观察currentMessage以从您提供的模拟服务中读取data

const dataServiceStub = { currentMessage: Observable.of(data) };

您似乎在构造对象spy。这意味着您的observable在创建spy之前已经触发。

在构造组件之前,请尝试对其进行spy

let service;
  beforeEach(() => {
         spyOn(service, 'currentMessage').and.returnValue(whatever you want to return);
         fixture = TestBed.createComponent(MyComponent);
         component = fixture.componentInstance;
         service = fixture.debugElement.injector.get(MyService);
         service.currentMessage = Observable.of(data);
   });

此外,您在.ts文件中的模式看起来有点不对劲。

this.data将始终未定义,因为您的if语句紧接在前一行之后,而不是在可观察返回之后。要解决此问题,您需要执行以下操作。

  export class MyComponent {
  private data;
  constructor(private myservice:MyService) {
      this.myService.currentMessage.subscribe((message) => {
        this.data = message
        if(this.data) {
          let response = true;
        } else {
          let response = false;
        }
     });

这可以通过检查if (message)并完全避免该字段来简化。希望这有帮助!

最新更新