3

I am adding unit tests in my Angular 7 app. I have 100 components to test, at least, and each one are failing because of the configuration: they need the declaration of each dependencies needed.

This is my component.spec.ts where is the configuration when I execute ng test:

    import { async, ComponentFixture, TestBed } from 
    '@angular/core/testing';

    import { myComponent } from './mycomponent';
    import { FontAwesomeModule } from '@fortawesome/angular- 
    fontawesome';

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

      beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [ myComponent ],
          imports: [
            FontAwesomeModule
            // + Others imports
          ]
        })
        .compileComponents();
      }));

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

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

In some components, I add providers. In some cases, I use a mockService. Everything I did, comes from angular docs.

Is there a way to configure easily or automatically unit tests (or end to end tests) with Angular, instead of to add every module needed manually?

I am using Angular 7, jasmine (3.3.1) and karma (4.0.0).

Fabien
  • 389
  • 2
  • 5
  • 15

2 Answers2

2

I usually import all dependencies individually as I make sure that the test only loads the dependencies that it actually needs. However, I have found a way to easily make all dependencies available to your test script without having to individually import each dependency. Instead of importing all dependencies individually, Import the module that is declaring your component to be tested. By importing the module on your unit test, you'll make all dependencies, including services and the component itself, available to your tests.

I usually take the trouble of declaring dependencies to avoid overloading the test with code it wont use which, in theory, will generally make run tests run slower. It sounds like this may be ok for your use case since you have so many tests to write.

Other than a loss in speed I know of no other drawbacks but there may be. If anyone knows of any please add them as comments to this post.

P.S. There may be dependencies that are being imported by your AppModule. These may need to be imported individually along with the component's declaring module.

Test Script

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { EasyImportComponent } from './easy-import.component';
import { EasyImportModule } from './easy-import.module';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ EasyImportModule ]
        //, declarations: [ EasyImportComponent ] <-- No longer needed since module declares this already
    })
    .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
A. Figueroa
  • 215
  • 1
  • 8
  • How do you import the module that is declaring your component to be tested? `imports: [ AppModule ]` ? – Fabien Feb 18 '19 at 15:53
  • Fabien, exactly. I do advise against importing the app module though. When I create a new component often create a module along with it. The module defines all dependencies and services, and makes the component easily consumable and reusable throughout the app. It is this module that I would import on your test. – A. Figueroa Feb 19 '19 at 21:40
  • `imports: [AppModule]` doesn't work for me. I got an error: `mycomponent is part of 2 declarations`. Can you show me an example? Or two examples with AppModule and like you said before? – Fabien Feb 19 '19 at 23:26
  • 1
    Fabien, that is an expected error. Your module already declares the component so your unit test no longer needs to declare components. I would avoid importing the AppModule, since you would be loading in memory the entire app for each test that is executed, but that's up to you. Please find the requested example code attached to the answer above. – A. Figueroa Feb 20 '19 at 15:36
1

I've made some researches with what is the best way for testing with Angular and I found an answer here, with several solutions and great explanations!

Fabien
  • 389
  • 2
  • 5
  • 15