简体   繁体   中英

Angular unit test mock parent component on child component

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!

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();
  });
});

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);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM