How to Unit Test a Directive In Angular 2?

后端 未结 2 1695
礼貌的吻别
礼貌的吻别 2020-12-28 12:32

Problem: I would like to be able to unit test a directive in Angular 2 to make sure that it properly compiles.

In Angular 1, it was possib

相关标签:
2条回答
  • 2020-12-28 12:48

    Took me a while to find a good example, a good person on angular gitter channel pointed me to look at the Angular Material Design 2 repository for examples. You can find a Directive test example here. This is the test file for the tooltip directive of Material Design 2. It looks like you have to test it as part of a component.

    0 讨论(0)
  • 2020-12-28 12:57

    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>'
        }
      });
    
      // ...      
    
    }));
    

    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();
          });
      }));
    

    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).

    0 讨论(0)
提交回复
热议问题