Angular 2单元测试组件,模拟ContentChildren [英] Angular 2 unit testing component, mocking ContentChildren

查看:52
本文介绍了Angular 2单元测试组件,模拟ContentChildren的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Angular 2 RC4中实现一个向导组件,现在我正在尝试编写som单元测试. Angular 2中的单元测试开始有据可查,但是我根本无法找出如何在组件中模拟内容查询的结果.

I am implementing a wizard component in Angular 2 RC4, and now I am trying to write som unit tests. Unit testing in Angular 2 is starting to get well documented, but I simply cannot find out how to mock the result of a content query in the component.

该应用程序具有2个组件(除了应用程序组件之外),即WizardComponent和WizardStepComponent.应用程序组件(app.ts)定义了向导及其模板中的步骤:

The app has 2 components (in addition to the app component), WizardComponent and WizardStepComponent. The app component (app.ts) defines the wizard and the steps in its template:

 <div>
  <fa-wizard>
    <fa-wizard-step stepTitle="First step">step 1 content</fa-wizard-step>
    <fa-wizard-step stepTitle="Second step">step 2 content</fa-wizard-step>
    <fa-wizard-step stepTitle="Third step">step 3 content</fa-wizard-step>
  </fa-wizard>
</div>

WizardComponent(wizard-component.ts)通过使用ContentChildren查询获得对步骤的引用.

The WizardComponent (wizard-component.ts) gets a reference to the steps by using a ContentChildren query.

@Component({
selector: 'fa-wizard',
template: `<div *ngFor="let step of steps">
            <ng-content></ng-content>
          </div>
          <div><button (click)="cycleSteps()">Cycle steps</button></div>`

})
export class WizardComponent implements AfterContentInit {
    @ContentChildren(WizardStepComponent) steps: QueryList<WizardStepComponent>;
....
}

问题在于如何在单元测试中模拟步骤变量:

The problem is how to mock the steps variable in the unit test:

describe('Wizard component', () => {
  it('should set first step active on init', async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
    return tcb
    .createAsync(WizardComponent)
    .then( (fixture) =>{
        let nativeElement = fixture.nativeElement;
        let testComponent: WizardComponent = fixture.componentInstance;

        //how to initialize testComponent.steps with mock data?

        fixture.detectChanges();

        expect(fixture.componentInstance.steps[0].active).toBe(true);
    });
  })));
});

我创建了一个 plunker ,它实现了一个非常简单的向导来演示该问题. Wizard-component.spec.ts文件包含单元测试.

I have created a plunker implementing a very simple wizard demonstrating the problem. The wizard-component.spec.ts file contains the unit test.

如果有人能指出我正确的方向,我将不胜感激.

If anyone can point me in the right direction, I would greatly appreciate it.

推荐答案

感谢 drewmoore 这个问题,我已经能够使它正常工作.

Thanks to drewmoore's answer in this question, I have been able to get this working.

关键是创建一个用于测试的包装器组件,该组件指定向导及其模板中的向导步骤.然后,Angular会为您查询内容并填充变量.

The key is to create a wrapper component for testing, which specifies the wizard and the wizard steps in it's template. Angular will then do the content query for you and populate the variable.

实现是针对Angular 6.0.0-beta.3

我的完整测试实现如下:

My full test implementation looks like this:

  //We need to wrap the WizardComponent in this component when testing, to have the wizard steps initialized
  @Component({
    selector: 'test-cmp',
    template: `<fa-wizard>
        <fa-wizard-step stepTitle="step1"></fa-wizard-step>
        <fa-wizard-step stepTitle="step2"></fa-wizard-step>
    </fa-wizard>`,
  })
  class TestWrapperComponent { }

  describe('Wizard component', () => {
    let component: WizardComponent;
    let fixture: ComponentFixture<TestWrapperComponent>;

    beforeEach(async(() => {
      TestBed.configureTestingModule({
        schemas: [ NO_ERRORS_SCHEMA ],
        declarations: [
          TestWrapperComponent,
          WizardComponent,
          WizardStepComponent
        ],
      }).compileComponents();
    }));

    beforeEach(() => {
      fixture = TestBed.createComponent(TestWrapperComponent);
      component = fixture.debugElement.children[0].componentInstance;
    });

    it('should set first step active on init', () => {
      expect(component.steps[0].active).toBe(true);
      expect(component.steps.length).toBe(3);
    });
  });

如果您有更好的/其他解决方案,也非常欢迎您添加答案.我将这个问题待一段时间.

If you have better/other solutions, you are very welcome to add you answer as well. I'll leave the question open for some time.

这篇关于Angular 2单元测试组件,模拟ContentChildren的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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