Jags
Jags

Reputation: 1761

How to test a component containing a third party directive

I have a basic component that contains the ngxPermissionsOnly directive which is working as expected. The library is on github here. I generated the component using the @angular-cli which also auto-generated the unit test.

e.g. Component

@Component({
    selector: 'project-card',
    template: '<div class="some-style"><div *ngxPermissionsOnly="['testPermission']"'>Hide Me</div></div>'
    styleUrls: ['./project-card.component.scss']
})
export class ProjectCardComponent implements OnInit {
    //Do some stuff here
}

e.g. Test

describe('ProjectCardComponent', () => {
    let component: ProjectCardComponent;
    let fixture: ComponentFixture<ProjectCardComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                ProjectCardComponent,
            ]
        })
        .compileComponents();
      }));

      beforeEach(() => {
          fixture = TestBed.createComponent(ProjectCardComponent);
          component = fixture.componentInstance;
          fixture.detectChanges();
      });

      it('should create', () => {
          expect(component).toBeTruthy();
      });
});

When I run the test I get the below error;

Can't bind to 'ngxPermissionsOnly' since it isn't a known property of 'div'

I tried adding the NgxPermissionsDirective to the TestBed declarations, however this directive is dependent on services from that library, and I would also have to inject them. I also tried importing the NgxPermissionsModule itself but it has it's own errors. It seems counter-intuitive to inject a whole bunch of services to test a simple component. Is there a way to mock this directive? Or another solution?

Upvotes: 5

Views: 6624

Answers (2)

Jags
Jags

Reputation: 1761

I had to import the NgxPermissionsModule and provide the NgxPermissionsService;

TestBed.configureTestingModule({
  imports: [
    NgxPermissionsModule.forRoot(),
    ...
  ],
  declarations: [
    ProjectCardComponent,
    ...
  ],
  providers: [
    NgxPermissionsService,
    ...
  ]
})

Upvotes: 3

Aleksi
Aleksi

Reputation: 540

I think you can just create mocked/stub directive by the same name in the test file and declare that in your test.

Or alternatively you could use CUSTOM_ELEMENTS_SCHEMA or NO_ERRORS_SCHEMA (more info here) as a schema in your tests:

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

describe('ProjectCardComponent', () => {
    let component: ProjectCardComponent;
    let fixture: ComponentFixture<ProjectCardComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                ProjectCardComponent,
            ],
            schemas: [CUSTOM_ELEMENTS_SCHEMA]
        })
        .compileComponents();
      }));

      beforeEach(() => {
          fixture = TestBed.createComponent(ProjectCardComponent);
          component = fixture.componentInstance;
          fixture.detectChanges();
      });

      it('should create', () => {
          expect(component).toBeTruthy();
      });
});

This will skip the unknown properties in your DOM, but this shouldn't be used if you want to actually test how the directive works with your component.

Upvotes: 1

Related Questions