如何在 Angular 2 中对指令进行单元测试? [英] How to Unit Test a Directive In Angular 2?

查看:32
本文介绍了如何在 Angular 2 中对指令进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:我希望能够在 Angular 2 中对指令进行单元测试,以确保它正确编译.

在 Angular 1 中,可以使用 $compile(angular.element(myElement) 服务,然后调用 $scope.$digest().我特别是我希望能够在单元测试中做到这一点,这样我就可以测试当 Angular 在 my-attr-指令 编译.

In Angular 1, it was possible to use$compile(angular.element(myElement) service and call $scope.$digest() after that. I specifically want to be able to do this in unit tests so I could test that when Angular ends up running across <div my-attr-directive/> in the code that my-attr-directive compiles.

限制条件:

  • Angular 2 using JAVASCRIPT. All sources somewhat related seem to require TS. Perhaps this resource truly does solve the problem and my understanding of TS is just that weak
  • Unit Test in Jasmine
  • Must be not be so hacky that my unit tests will eventually break. See a related SO post on compiling HTML manually in Angular 2

推荐答案

使用 TestBed 测试编译指令

假设您有以下指令:

Testing compiled directive using TestBed

Let's say you have a following directive:

@Directive({
  selector: '[my-directive]',
})
class MyDirective {
  public directiveProperty = 'hi!';
}

您需要做的是创建一个使用该指令的组件(它可以仅用于测试目的):

What you have to do, is to create a component that uses the directive (it can be just for testing purpose):

@Component({
  selector: 'my-test-component',
  template: ''
})
class TestComponent {}

现在您需要创建一个声明它们的模块:

Now you need to create a module that has them declared:

describe('App', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        TestComponent,
        MyDirective
      ]
    });
  });

  // ...

});

您可以将模板(包含指令)添加到组件中,但可以通过在测试中覆盖模板来动态处理:

You can add the template (that contains directive) to the component, but it can be handled dynamically by overwriting the template in test:

it('should be able to test directive', async(() => {
  TestBed.overrideComponent(TestComponent, {
    set: {
      template: '<div my-directive></div>'
    }
  });

  // ...      

}));

现在您可以尝试编译该组件,并使用By.directive 对其进行查询.最后,有可能使用 injector 获取指令实例:

Now you can try to compile the component, and query it using By.directive. At the very end, there is a possibility to get a directive instance using the injector:

TestBed.compileComponents().then(() => {
  const fixture = TestBed.createComponent(TestComponent);
  const directiveEl = fixture.debugElement.query(By.directive(MyDirective));
  expect(directiveEl).not.toBeNull();

  const directiveInstance = directiveEl.injector.get(MyDirective);
  expect(directiveInstance.directiveProperty).toBe('hi!');
}); 

# 旧答案:

要测试一个指令,你需要用它创建一个假组件:

# Old answer:

To test a directive you need to create a fake component with it:

@Component({
  selector: 'test-cmp',
  directives: [MyAttrDirective],
  template: ''
})
class TestComponent {}

您可以在组件本身中添加模板,但可以通过在测试中覆盖模板来动态处理:

You can add the template in the component itself but it can be handled dynamically by overwriting the template in test:

it('Should setup with conversation', inject([TestComponentBuilder], (testComponentBuilder: TestComponentBuilder) => {
    return testComponentBuilder
      .overrideTemplate(TestComponent, `<div my-attr-directive></div>`)
      .createAsync(TestComponent)
      .then((fixture: ComponentFixture<TestComponent>) => {
        fixture.detectChanges();
        const directiveEl = fixture.debugElement.query(By.css('[my-attr-directive]'));
        expect(directiveEl.nativeElement).toBeDefined();
      });
  }));

请注意,您可以测试指令呈现的内容,但我找不到以组件方式测试指令的方法(没有用于指令的 TestComponentBuilder).

Note that you're able to test what directive renders but I couldn't find the way to test a directive in a way components are (there is no TestComponentBuilder for directives).

这篇关于如何在 Angular 2 中对指令进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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