测试组件¶
测试准备¶
改造原先的Login组件,引入数据模型、inputs、outputs以及表单。
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 29 30 31 32 33 34 35 36 | import {Component, EventEmitter, Input, Output} from '@angular/core'; export class User { constructor(public email: string, public password: string) { } } @Component({ selector: 'app-login', template: ` <form> <label>Email</label> <input type="email" #email> <label>Password</label> <input type="password" #password> <button type="button" (click)="login(email.value, password.value)" [disabled]="!enabled">Login </button> </form> ` }) export class LoginComponent { @Output() loggedIn = new EventEmitter<User>(); @Input() enabled = true; login(email, password) { console.log(`Login ${email} ${password}`); if (email && password) { console.log(`Emitting`); this.loggedIn.emit(new User(email, password)); } } } |
- 建立User类封装登录用户信息.
- button按钮通过输入属性enabled控制是否显示,点击按钮将调用login方法
- 组件将抛出loggedIn事件.
测试代码:
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 | describe('Component: Login', () => { let component: LoginComponent; let fixture: ComponentFixture<LoginComponent>; let submitEl: DebugElement; let loginEl: DebugElement; let passwordEl: DebugElement; beforeEach(() => { TestBed.configureTestingModule({ declarations: [LoginComponent] }); // create component and test fixture fixture = TestBed.createComponent(LoginComponent); // get test component from the fixture component = fixture.componentInstance; submitEl = fixture.debugElement.query(By.css('button')); loginEl = fixture.debugElement.query(By.css('input[type=email]')); passwordEl = fixture.debugElement.query(By.css('input[type=password]')); }); }); |
测试 @Inputs¶
为了测试Input,我们需要做到:
- 能够改变组件的enabled输入值.
- 能够验证按钮的可用状态与enabled值是一致的.
1 2 3 4 5 6 7 8 9 | it('Setting enabled to false disables the submit button', () => { component.enabled = false; }); it('Setting enabled to false disables the submit button', () => { component.enabled = false; fixture.detectChanges(); expect(submitEl.nativeElement.disabled).toBeTruthy(); }); |
不要忘记调用detechChanges方法来更新view
测试 @Outputs¶
首先需要能够跟踪到组件抛出的事件
1 2 3 4 5 6 7 8 | it('Entering email and password emits loggedIn event', () => { let user: User; component.loggedIn.subscribe((value) => user = value); expect(user.email).toBe("test@example.com"); expect(user.password).toBe("123456"); }); |
关键点是 component.loggedIn.subscribe((value) => user = value);
output事件实际上是一个Observable对象,因此我们可以订阅它。每次变化时订阅者都将获得通知。 随后可以对获得的user对象进行断言判断
那如何触发这个事件呢?当然我们可以调用component.login方法,但是我们更希望能够从view上触发这个方法。
首先我们给email与password输入框赋值
loginEl.nativeElement.value = "test@example.com";
passwordEl.nativeElement.value = "123456";
然后通过submit按钮触发事件,并且需要在订阅完成之后再执行。
1 2 3 4 5 6 7 8 9 10 11 12 | it('Entering email and password emits loggedIn event', () => { let user: User; loginEl.nativeElement.value = "test@example.com"; passwordEl.nativeElement.value = "123456"; component.loggedIn.subscribe((value) => user = value); submitEl.triggerEventHandler('click', null); expect(user.email).toBe("test@example.com"); expect(user.password).toBe("123456"); }); |