【问题标题】:Angular2 final version: Injected Service method under unit test returning undefinedAngular2最终版本:单元测试下的注入服务方法返回未定义
【发布时间】:2017-02-25 14:33:09
【问题描述】:

我正在尝试在一个组件上编写一些单元测试,将一些服务注入其中,以从服务器加载数据。数据通过 OnInit() 方法加载到此组件中。我正在尝试该服务方法使用 spyOn 返回一些虚拟数据。以下是单元测试设置 -

let comp: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let staticDataService: any;
let spy: jasmine.Spy;
let allCountries: string[];

describe('MyComponent', () => {
beforeEach( async(() => {

    TestBed.configureTestingModule({
        imports : [ FormsModule, HttpModule ],
        declarations : [MyComponent],
        providers: [ StaticDataService ]
    })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    comp = fixture.componentInstance;
    staticDataService = fixture.debugElement.injector.get(StaticDataService);
    allCountries = [] = ["US", "UK"];
    spy = spyOn(staticDataService, 'getCountries').and.returnValue(Promise.resolve(allCountries));
    });
it('Countries should be set', () => {
    expect(comp.allCountries).toEqual(allCountries);
    }); 
});

以下是我正在单元测试的组件类 -

@Component({
  moduleId: module.id,
  selector: 'myeditor',
  templateUrl: 'my.component.html',
  styleUrls: ['my.component.css']
})
export class MyComponent implements OnInit {
  allCountries: string[];
  constructor(private _staticDataServices: StaticDataService) {}
  ngOnInit() {
    this.getDataFromServer();
  }

  getDataFromServer()
  {
    this.allCountries = this._staticDataServices.getCountries();
  }

我收到以下错误 -

    Chrome 53.0.2785 (Windows 7 0.0.0) MyComponent Countries should be set FAILED
    [1]     Expected undefined to equal [ 'US', 'UK' ].

在相同的单元测试下,很少有其他测试可以正常工作,它们不依赖于注入的服务。在测试由服务设置的属性时获得“未定义”。 有人可以帮助我在这里做错了吗?

谢谢

【问题讨论】:

    标签: unit-testing angular typescript jasmine spyon


    【解决方案1】:
    1. 您需要调用fixture.detectChanges() 才能调用ngOnInit

      fixture = TestBed.createComponent(MyComponent);
      fixture.detectChanges();
      
    2. getCountries 返回一个Promise 所以你需要then 它,否则allCountries 的值将只是承诺而不是数据

      getDataFromServer() {
        this._staticDataServices.getCountries().then(data => {
          this.countries = data;
        });
      }
      
    3. 由于promise是异步的,所以需要使用async,并通过调用fixture.whenStable()等待异步任务完成

      import { async } from '@angular/core/testing';
      
      it('...', async(() => {
        fixture.whenStable().then(() => {
          expect(comp.allCountries).toEqual(allCountries);
        })
      })
      

    UDPATE

    没有看到StaticDataService,我猜你正试图将Http 注入其中。如果没有进一步的配置,这将无法在测试环境中工作。我建议你做的只是让服务成为一个模拟

    staticDataService = {
      getCountries: jasmine.createSpy('getCountries').and.returnValue(...);
    }
    
    providers: [
      { provide: StaticDataService, useValue: staticDataService }
    ]
    

    【讨论】:

    • 感谢您的回复。当我应用这些更改时,我收到以下错误 -
    • 感谢您的回复。当我应用这些更改时,我收到以下错误 - [1] TypeError: this._staticDataService.getCountries(...).subscribe is not a function 不确定为什么在应该被方法/值覆盖时调用此方法在 spyOn 中指定。
    • 您不能在承诺上调用subscribe(这是模拟返回的内容)。这仅适用于可观察者。它们是不同的东西。您需要致电then 承诺。如果你想在你的模拟中发出一个 observable,那么and.returnValue(Observable.of(allCountries))
    • 你需要导入rxjs/add/observable/of
    • 谢谢,这有帮助。它通过 OnInit 方法。进一步需要解决相同测试中出现的一些html解析错误..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    相关资源
    最近更新 更多