加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-17 08:07:21 所属栏目:安全 来源:网络整理
导读:我如何在茉莉花测试中模拟子组件? 我有MyComponent,它使用MyNavbarComponent和MyToolbarComponent import {Component} from 'angular2/core';import {MyNavbarComponent} from './my-navbar.component';import {MyToolbarComponent} from './my-toolbar.co
我如何在茉莉花测试中模拟子组件?

我有MyComponent,它使用MyNavbarComponent和MyToolbarComponent

import {Component} from 'angular2/core';
import {MyNavbarComponent} from './my-navbar.component';
import {MyToolbarComponent} from './my-toolbar.component';

@Component({
  selector: 'my-app',template: `
    <my-toolbar></my-toolbar>
    {{foo}}
    <my-navbar></my-navbar>
  `,directives: [MyNavbarComponent,MyToolbarComponent]
})
export class MyComponent {}

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

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

beforeEach(() => {
    setBaseTestProviders(
      TEST_BROWSER_PLATFORM_PROVIDERS,TEST_BROWSER_APPLICATION_PROVIDERS
    );

    //TODO: want to mock unnecessary directives for this component test
    // which are MyNavbarComponent and MyToolbarComponent
  })

  it('should bind to {{foo}}',injectAsync([TestComponentBuilder],(tcb) => {
    return tcb.createAsync(MyComponent).then((fixture) => {
      let DOM = fixture.nativeElement;
      let myComponent = fixture.componentInstance;
      myComponent.foo = 'FOO';
      fixture.detectChanges();
      expect(DOM.innerHTML).toMatch('FOO');
    });
  });

这是我的榜样

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

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

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

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

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

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

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

schemas: [CUSTOM_ELEMENTS_SCHEMA]

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

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

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

@Directive({
  selector: 'app-task'
})
class MockTaskDirective {
  @Input('task')
  public task: ITask;
  @Output('click')
  public clickEmitter = new EventEmitter<void>();
}

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

let fixture : ComponentFixture<TaskListComponent>;
let cmp : TaskListComponent;

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [TaskListComponent,**MockTaskDirective**],// schemas: [CUSTOM_ELEMENTS_SCHEMA],providers: [
      {
        provide: TasksService,useClass: MockService
      }
    ]
  });

  fixture = TestBed.createComponent(TaskListComponent);
  **fixture.autoDetectChanges();**
  cmp = fixture.componentInstance;
});

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

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

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

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

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

it('should contain task component',()=> {
  // Arrange
  const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));

  // Assert
  expect(mockTaskEl).toBeTruthy();
});
it('should pass down task object',()=>{
  // Arrange
  const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
  const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;

  // Assert
  expect(mockTaskCmp.task).toBeTruthy();
  expect(mockTaskCmp.task.name).toBe('1');
});
it('should refresh when task is clicked',()=> {
  // Arrange
  spyOn(cmp,'refresh');
  const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
  const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;

  // Act
  mockTaskCmp.clickEmitter.emit();

  // Assert
  expect(cmp.refresh).toHaveBeenCalled();
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读