单元测试 – angular2测试,我如何模拟子组件

前端之家收集整理的这篇文章主要介绍了单元测试 – angular2测试,我如何模拟子组件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我如何在茉莉花测试中模拟子组件?

我有MyComponent,它使用MyNavbarComponent和MyToolbarComponent

  1. import {Component} from 'angular2/core';
  2. import {MyNavbarComponent} from './my-navbar.component';
  3. import {MyToolbarComponent} from './my-toolbar.component';
  4.  
  5. @Component({
  6. selector: 'my-app',template: `
  7. <my-toolbar></my-toolbar>
  8. {{foo}}
  9. <my-navbar></my-navbar>
  10. `,directives: [MyNavbarComponent,MyToolbarComponent]
  11. })
  12. export class MyComponent {}

当我测试这个组件时,我不想加载和测试这两个子组件; MyNavbarComponent,MyToolbarComponent,所以我想嘲笑它。

我知道如何使用提供(MyService,useClass(…))来嘲笑服务,但我不知道如何模拟指令;组件;

  1. beforeEach(() => {
  2. setBaseTestProviders(
  3. TEST_BROWSER_PLATFORM_PROVIDERS,TEST_BROWSER_APPLICATION_PROVIDERS
  4. );
  5.  
  6. //TODO: want to mock unnecessary directives for this component test
  7. // which are MyNavbarComponent and MyToolbarComponent
  8. })
  9.  
  10. it('should bind to {{foo}}',injectAsync([TestComponentBuilder],(tcb) => {
  11. return tcb.createAsync(MyComponent).then((fixture) => {
  12. let DOM = fixture.nativeElement;
  13. let myComponent = fixture.componentInstance;
  14. myComponent.foo = 'FOO';
  15. fixture.detectChanges();
  16. expect(DOM.innerHTML).toMatch('FOO');
  17. });
  18. });

这是我的榜样

http://plnkr.co/edit/q1l1y8?p=preview

根据要求,我发布了关于如何通过输入/输出模拟子组件的另一个答案:

所以让我们开始说我们有TaskListComponent显示任务,并且当其中一个被点击时刷新:

  1. <div id="task-list">
  2. <div *ngFor="let task of (tasks$ | async)">
  3. <app-task [task]="task" (click)="refresh()"></app-task>
  4. </div>
  5. </div>

应用任务是具有[任务]输入和(点击)输出的子组件。

好的,现在我们要为我的TaskListComponent编写测试,当然我们不想测试真正的app-task组件。

所以@Klas建议我们可以配置我们的TestModule:

  1. schemas: [CUSTOM_ELEMENTS_SCHEMA]

我们可能不会在构建或运行时收到任何错误,但是除了子组件的存在之外,我们将无法进行测试。

那么我们如何模拟子组件呢?

首先我们为我们的子组件定义一个mock指令(同一个选择器):

  1. @Directive({
  2. selector: 'app-task'
  3. })
  4. class MockTaskDirective {
  5. @Input('task')
  6. public task: ITask;
  7. @Output('click')
  8. public clickEmitter = new EventEmitter<void>();
  9. }

现在我们将在测试模块中声明它:

  1. let fixture : ComponentFixture<TaskListComponent>;
  2. let cmp : TaskListComponent;
  3.  
  4. beforeEach(() => {
  5. TestBed.configureTestingModule({
  6. declarations: [TaskListComponent,**MockTaskDirective**],// schemas: [CUSTOM_ELEMENTS_SCHEMA],providers: [
  7. {
  8. provide: TasksService,useClass: MockService
  9. }
  10. ]
  11. });
  12.  
  13. fixture = TestBed.createComponent(TaskListComponent);
  14. **fixture.autoDetectChanges();**
  15. cmp = fixture.componentInstance;
  16. });

>请注意,由于灯具的子组件的生成在其创建后异步发生,因此我们激活其autoDetectChanges功能

在我们的测试中,我们现在可以查询指令,访问其DebugElement的注入器,并通过它获取我们的模拟指令实例:

  1. import { By } from '@angular/platform-browser';
  2. const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
  3. const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;

[这部分通常在前面的部分,更清洁的代码。]

从这里,测试是一块蛋糕:)

  1. it('should contain task component',()=> {
  2. // Arrange
  3. const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
  4.  
  5. // Assert
  6. expect(mockTaskEl).toBeTruthy();
  7. });
  8. it('should pass down task object',()=>{
  9. // Arrange
  10. const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
  11. const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;
  12.  
  13. // Assert
  14. expect(mockTaskCmp.task).toBeTruthy();
  15. expect(mockTaskCmp.task.name).toBe('1');
  16. });
  17. it('should refresh when task is clicked',()=> {
  18. // Arrange
  19. spyOn(cmp,'refresh');
  20. const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
  21. const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;
  22.  
  23. // Act
  24. mockTaskCmp.clickEmitter.emit();
  25.  
  26. // Assert
  27. expect(cmp.refresh).toHaveBeenCalled();
  28. });

猜你在找的Angularjs相关文章