Home > other >  Angular unit test mock parent component on child component
Angular unit test mock parent component on child component

Time:08-27

I'm trying to test the child component, but it requires a parent component for its main functionalities.

How can I test the child component with a "mock" parent?

(Using Jest, Angular 14, TypeScript)

parent.component.ts

@Component({...})
export class ParentComponent {
    onChildClicked(child: ChildComponent) {
        // ...
    }
}

child.component.ts

@Component({...})
export class ChildComponent {
  constructor(private parent: ParentComponent) {}

  onClick() {
    this.parent.onChildClicked(this);
  }
}

child.component.spec.ts

describe("ChildComponent", () => {
  it("should be rendered", async () => {
    const { container } = await render(ChildComponent, {
      declarations: [ParentComponent],
    });
    expect(container).toBeTruthy();
  });
});

page.component.html

<app-parent>
  <app-child></app-child>
</app-parent>

Test output:

ChildComponent › should be rendered

    NullInjectorError: R3InjectorError(DynamicTestModule)[ParentComponent -> ParentComponent]:
      NullInjectorError: No provider for ParentComponent!

CodePudding user response:

I found a solution. Make the parent component avaible as a provider for the child component.

child.component.spec.ts


describe("ChildComponent", () => {
  it("should be rendered", async () => {
    const { container } = await render(ChildComponent, {
      declarations: [ParentComponent],
      providers: [ParentComponent]
    });
    expect(container).toBeTruthy();
  });
});

CodePudding user response:

Why you are calling parent function like this in child component, and you should not inject Parent component as dependency in child component.

If you want to call parent function based on some event click inside child component then use @Output() event emitter.

Like below

Parent Component

 onChildClicked(value) {
            console.log(value);
 }





<app-parent>
  <app-child (childClicked)='onChildClicked($event)'></app-child>
</app-parent>

Child component

@Output() childClicked = new EventEmitter()

onClick() {  
        this.childClicked.emit(value_you_want_to_pass);
    }
  • Related