TestBed

Angular Test Bed (ATB)也是个测试框架,只不过仅用于测试Angular框架.

配置

我们先演示一下将之前纯粹Jasmine框架写的Login组件的测试代码转换成ATB方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/* tslint:disable:no-unused-variable */
import {TestBed, ComponentFixture} from '@angular/core/testing';
import {LoginComponent} from './login.component';
import {AuthService} from "./auth.service";

describe('Component: Login', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({ //使用TestBed配置测试模块TestingModule
      declarations: [LoginComponent],
      providers: [AuthService]
    });
  });
});

在beforeEach方法中使用TestBed配置一个测试模块,该模块可用来初始化组件、注入依赖等。
配置方式与NgModule配置相同。

Fixtures 与 DI

一旦ATB配置好,即可用来初始化组件、解析依赖注入:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* tslint:disable:no-unused-variable */
import {TestBed, ComponentFixture} from '@angular/core/testing';
import {LoginComponent} from './login.component';
import {AuthService} from "./auth.service";

describe('Component: Login', () => {

  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>; 
  let authService: AuthService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      providers: [AuthService]
    });

    // create component and test fixture
    fixture = TestBed.createComponent(LoginComponent); 

    // get test component from the fixture
    component = fixture.componentInstance; 

    // UserService provided to the TestBed
    authService = TestBed.get(AuthService); 

  });
});

Fixture是对组件的一个包装,包含其html模板。

因为LoginComponent 没有内置独立的injector,上面代码中通过TestBed获取的AuthService对象与注入到组件中的服务对象是同一个对象.

测试用例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
it('canLogin returns false when the user is not authenticated', () => {
  spyOn(authService, 'isAuthenticated').and.returnValue(false);
  expect(component.needsLogin()).toBeTruthy();
  expect(authService.isAuthenticated).toHaveBeenCalled();
});

it('canLogin returns false when the user is not authenticated', () => {
  spyOn(authService, 'isAuthenticated').and.returnValue(true);
  expect(component.needsLogin()).toBeFalsy();
  expect(authService.isAuthenticated).toHaveBeenCalled();
});

何时使用 ATB

  • 可以用来测试指令、组件模板的交互逻辑
  • 方便测试组件变化事件
  • 可以测试Angular的DI框架
  • 可以模拟使用NgModule的配置进行测试
  • 可以测试点击、输入等事件

总结

ATB 让测试像是在实际应用中运行一样真实,尤其当需要测试组件变化、属性绑定时其优势更能体现出来。