Is unit test required for each and every component in angular 4?

Viewed 1353

Angular 4 comes with cli tool. When you create a new component, it generates a component file, template file, stylesheet and spec file (unit test).

MainComponent does nothing but is just a placeholder for other components, example

mainComponent contains following in its template

<navbar-component></navbar-component> 
<router-outlet></router-outlet>
<footer-component></footer-component>

In the unit test file(main.component.spec.ts), we have to import all these components, and the other dependencies(like if you are using angular material library, icon module or services and dependencies of these three components), router module and you have to stub the router etc.

Is it worth to keep the unit test file for this component? or should I delete the spec files for these type of components

2 Answers

You have to break your angular applications to different modules. It is not recommended to create entire applications of many components with only one module.

That being said, you can import the module containing the maincomponent while configuring the TestBed. In main.component.spec.ts, you would have imported other components like this

Before

beforeEach(async(() => {
  TestBed.configureTestingModule({
      imports:[RouterModule.forRoot(routes)
      ....
      ....],
      declarations: [NavbarComponent,
      FooterComponent
      ....
      ....]
    })
    .compileComponents();
}));

Instead, you can directly import the AppModule.

After

import AppModule from '../app.module'

beforeEach(async(() => {
  TestBed.configureTestingModule({
      imports:[AppModule]
    })
    .compileComponents();
}));

Here AppModule contains the component NavbarComponent, FooterComponent.

EDIT

Do it with caution. Doing this is kind of short cut to solve the original problem. Because you are using real services, and not mocking them. So if you are using service which calls the server, then your test will also call the server. If your service deals with local storage, then your test will also manipulate the local storage.

Better way to do this is combination of CUSTOM_ELEMENTS_SCHEMA and stubbing of services.

CUSTOM_ELEMENTS_SCHEMA will ignore

  • any non-Angular elements with a - in their name,
  • any properties on elements with a - in their name which is the common rule for custom elements.

So it will not throw error if you are using some <md-icon> or <app-footer>.

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

By stubbing your router, you will avoid hitting your server, which is the recommended way. Please read more about stubbing services at offical angular guide

Injecting the real UserService could be a nightmare. The real service might ask the user for login credentials and attempt to reach an authentication server. These behaviors can be hard to intercept. It is far easier and safer to create and register a test double in place of the real UserService.

Testing your code is best practice, however, if a component isn't doing anything, then there is nothing to test. I would still keep the spec file in case someone adds functionality in the future though.

If you don't want tests period, then you can run ng new with either --skip-tests or the --minimal flags. The latter will also put your styles and template files inline.

Remember, the cli will do most of the work for you and you can always use the schemas: [ CUSTOM_ELEMENTS_SCHEMA ] in your TestBed module to have the tests ignore components referenced in the template.

References:

Related