4

I am running an Angular 5 application with the default test setup (Jasmine + Karma).

Let's say there is a component named Parent, having a method executing a method on child component.

parent.component.ts

@Component({
  selector: 'parent',
...
export class ParentComponent implements {
  @ViewChild(ChildComponent) childComponent: ChildComponent;

  executeChildComponentMethod() {
    this.childComponent.methodToTest();
  }
}

parent.component.spec.ts

import { ParentComponent } from './parent.component'

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

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

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

  it('should trigger executeChildComponentMethod', () => {
    component.executeChildComponentMethod()
  });
});

This results in the tests throwing error saying, unable to execute methodToTest of undefined.. which means the child component is not instantiated.

Have tried approaches like instantiating a child component inside the it block, injecting the child component to the it block and instantiating child component from another fixture (for child component) in the test block but to no avail.

How can I get the test working?

purezen
  • 612
  • 12
  • 29
  • Have you checked the answer? Feel free to ask any doubts on the answer. – Amit Chigadani Jul 04 '18 at 08:05
  • I tried that solution. Not getting the component is undefined error.. but getting different errors. First I got pipes not found.. then I included those pipes in the declarations array. Now I am getting error 'No provider for ControlContainer'. Not sure if I am going in the correct path. – purezen Jul 04 '18 at 08:15
  • Check updated answer to get rid of child providers. – Amit Chigadani Jul 04 '18 at 09:09
  • I am actually trying to test the child component individually to check if there's an issue. And it is giving an error saying 'No provider for ControlContainer' for a line ' [ERROR ->] – purezen Jul 05 '18 at 11:05
  • Does your app run successfully after doing `ng serve`? If so you will have to add your child component template in your question mentioning that error. Well, that is probably another question. If you google it you will get many posts. I would suggest you to close this question and ask new one, since this question is related to child component invocation only. Else it would be confusing for future readers. – Amit Chigadani Jul 05 '18 at 11:11
  • Yes, it is running fine. I am waiting to get the test for child component running. If the problem with the parent component test is resolved then, I can close this question because if it doesn't and I close it now I'll have to open same question again. – purezen Jul 05 '18 at 11:18
  • Again I am saying it, you need not check the behaviour of child component while doing unit testing for parent. You can simply mock. This will make the parent test easier. You can check the behaviour of your child method as a part of child unit testing only. – Amit Chigadani Jul 05 '18 at 11:25
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/174415/discussion-between-purezen-and-amit-chigadani). – purezen Jul 05 '18 at 11:26

1 Answers1

5

Add ChildComponent to declarations array, so that it is part of your unit test, which means it will be rendered in the view.

 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ParentComponent, ChildComponent],
        schemas: [NO_ERRORS_SCHEMA]
      })
      .compileComponents();
  }));

Note : You may have to add providers of ChildComponent as well.

EDIT :

Alternate approach

First of all, as a part of unit testing you should not be testing the behavior of child component inside parent component. If you want to check only if child component method is called or not, then you may mock the child component and define a method that you are testing inside it. This way, you need not depend on the child providers during testing.

See here for mocking child components.

Amit Chigadani
  • 28,482
  • 13
  • 80
  • 98