Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Unit Testing - Mock Child Component using Stub

I am trying to unit test a component that has a child component that I want to mock. I don't want to use the NO_ERRORS_SCHEMA cause the drawbacks associated. I am trying to use a stub/dummy child component. The code is as follows:

parent.component.ts

@Component({
  selector: 'parent',
  template: `
    <!-- Does other things -->
    <child></child>
  `
})
export class ParentComponent { }

child.component.ts

@Component({
  selector: 'child',
  template: '<!-- Does something -->'
})
export class ChildComponent {
  @Input() input1: string;
  @Input() input2?: number;
}

parent.component.spec.ts

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;

  @Component({
    selector: 'child',
    template: '<div></div>'
  })
  class ChildStubComponent {
    @Input() input1: string;
    @Input() input2: number;
  }

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

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

The problem I'm having is that angular is complaining with the following error:

Failed: Template parse errors:
More than one component matched on this element.
Make sure that only one component's selector can match a given element.

I'm using Angular version 8 if that helps. Everywhere I looked so far shows that you stub a child component the same way I am doing now. Using ngMocks is not an option at the moment.

EDIT Tried using ngMock but this only has the same problem. Any help would be very much appreciated!

Solution

Got it working. Problem was that the AppRoutingModule had the real component imported already.

like image 259
Clev_James23 Avatar asked Dec 10 '25 03:12

Clev_James23


1 Answers

For the nested component, we can mock them like this: https://angular.io/guide/testing-components-scenarios#stubbing-unneeded-components

In conclusion, your parent.component.spec.ts should be:

import { HttpClientTestingModule} from '@angular/common/http/testing';
import { Component } from '@angular/core';

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;


 @Component({selector: 'child', template: ''})
 class ChildStubComponent {}

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientTestingModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
like image 51
German Quinteros Avatar answered Dec 12 '25 19:12

German Quinteros