在 Angular 2 ngOnInit 中测试承诺 [英] Testing promise in Angular 2 ngOnInit

查看:12
本文介绍了在 Angular 2 ngOnInit 中测试承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Angular 2 组件,我正在尝试对其进行测试,但我遇到了问题,因为数据是在 ngOnInit 函数中设置的,因此在单元测试中无法立即使用.

I have an Angular 2 component I am trying to put under test, but I am having trouble because the data is set in the ngOnInit function, so is not immediately available in the unit test.

用户视图.component.ts:

user-view.component.ts:

import {Component, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';

import {User} from './user';
import {UserService} from './user.service';

@Component({
  selector: 'user-view',
  templateUrl: './components/users/view.html'
})
export class UserViewComponent implements OnInit {
  public user: User;

  constructor(
    private _routeParams: RouteParams,
    private _userService: UserService
  ) {}

  ngOnInit() {
    const id: number = parseInt(this._routeParams.get('id'));

    this._userService
      .getUser(id)
      .then(user => {
        console.info(user);
        this.user = user;
      });
  }
}

user.service.ts:

user.service.ts:

import {Injectable} from 'angular2/core';

// mock-users is a static JS array
import {users} from './mock-users';
import {User} from './user';

@Injectable()
export class UserService {
  getUsers() : Promise<User[]> {
    return Promise.resolve(users);
  }

  getUser(id: number) : Promise<User> {
    return Promise.resolve(users[id]);
  }
}

用户视图.component.spec.ts:

user-view.component.spec.ts:

import {
  beforeEachProviders,
  describe,
  expect,
  it,
  injectAsync,
  TestComponentBuilder
} from 'angular2/testing';
import {provide} from 'angular2/core';
import {RouteParams} from 'angular2/router';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';

import {UserViewComponent} from './user-view.component';

import {UserService} from './user.service';

export function main() {
  describe('User view component', () => {
    beforeEachProviders(() => [
      provide(RouteParams, { useValue: new RouteParams({ id: '0' }) }),
      UserService
    ]);

    it('should have a name', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
      return tcb.createAsync(UserViewComponent)
        .then((rootTC) => {
          spyOn(console, 'info');

          let uvDOMEl = rootTC.nativeElement;
          rootTC.detectChanges();

          expect(console.info).toHaveBeenCalledWith(0);
          expect(DOM.querySelectorAll(uvDOMEl, 'h2').length).toBe(0);
        });
    }));

  });
}

路由参数正确传递,但在运行测试之前视图没有改变.如何设置在解决 ngOnInit 中的承诺后发生的测试?

The route param is getting passed correctly, but the view hasn't changed before the tests are run. How do I set up a test that happens after the promise in ngOnInit is resolved?

推荐答案

Return a Promise from #ngOnInit:

Return a Promise from #ngOnInit:

ngOnInit(): Promise<any> {
  const id: number = parseInt(this._routeParams.get('id'));

  return this._userService
    .getUser(id)
    .then(user => {
      console.info(user);
      this.user = user;
    });
}

几天前我遇到了同样的问题,发现这是最可行的解决方案.据我所知,它不会影响应用程序中的其他任何地方.由于 #ngOnInit 在源的 TypeScript 中没有指定返回类型,我怀疑源代码中的任何内容都期望从中返回值.

I ran into the same issue a few days back, and found this to be the most workable solution. As far as I can tell, it doesn't impact anywhere else in the application; since #ngOnInit has no specified return type in the source's TypeScript, I doubt anything in the source code is expecting a return value from that.

链接到 OnInit:https://github.com/angular/angular/blob/2.0.0-beta.6/modules/angular2/src/core/linker/interfaces.ts#L79-L122

在您的测试中,您将返回一个新的 Promise:

In your test, you'd return a new Promise:

it('should have a name', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
  // Create a new Promise to allow greater control over when the test finishes
  //
  return new Promise((resolve, reject) => {
    tcb.createAsync(UserViewComponent)
      .then((rootTC) => {

        // Call ngOnInit manually and put your test inside the callback
        //
        rootTC.debugElement.componentInstance.ngOnInit().then(() => {
          spyOn(console, 'info');

          let uvDOMEl = rootTC.nativeElement;
          rootTC.detectChanges();

          expect(console.info).toHaveBeenCalledWith(0);
          expect(DOM.querySelectorAll(uvDOMEl, 'h2').length).toBe(0);

          // Test is done
          //
          resolve();
        });

      });
    }));

  }

这篇关于在 Angular 2 ngOnInit 中测试承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆