How to Unit Test a Directive In Angular 2?
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).
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.