spectator: All instances of a MockComponent share the same event emitter, therefore I cannot emit events on individual instances.

Hi!

First of, thanks for an awesome testing framework 😃

I’m currently mocking some outputs using MockComponent. There seems to be an issue where all instances of the mock component share the same event emitter. Calling emit on a single instance will therefore call the bound method multiple times, once for each instance.

Here’s a test to demonstrate this:

import { Component, EventEmitter, Output } from "@angular/core";
import { createTestComponentFactory, MockComponent } from "@netbasal/spectator";

@Component({
    selector: "app-subcomponent-component",
    template: ``,
})
class SubcomponentDemoComponent {
    @Output()
    public emitter = new EventEmitter();
}

@Component({
    selector: "app-demo-component",
    template: `
        <app-subcomponent-demo (emitter)="boundMethod()"></app-subcomponent-demo>
        <app-subcomponent-demo (emitter)="boundMethod()"></app-subcomponent-demo>
    `,
})
class DemoComponent {
    public boundMethod() {}
}

describe("spectator", () => {
    const create = createTestComponentFactory({
        component: DemoComponent,
        shallow: true,
        declarations: [
            MockComponent({
                selector: "app-subcomponent-demo",
                identifier: SubcomponentDemoComponent,
                outputs: ["emitter"],
            }),
        ],
    });

    it("should differentiate between instances of event emitters", () => {
        const spectator = create({}, false);
        spyOn(spectator.component, "boundMethod");

        const instances = spectator.queryAll<SubcomponentDemoComponent>(SubcomponentDemoComponent);
        instances[0].emitter.emit();
        expect(spectator.component.boundMethod).toHaveBeenCalledTimes(1);
    });
});

The function, boundMethod should only be called once because only one value is emitted, however, it is called twice.

Could you have a look into this?

Thanks and cheers, Oliver

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (10 by maintainers)

Commits related to this issue

Most upvoted comments

All right, maybe it’s good to update the docs accordingly (and deprecate the Spectator one, and update the existing unit tests to properly demonstrate this compatibility).

@ike18t Yes, we are using ng-mocks. Spectator and ng-mocks together are a win-win 😃

I came across this lib after reading @NetanelBasal 's medium article. I’m stoked that you guys are going to pull in ng-mocks. Let me know if there is anything you guys need from me.

Hey all, thanks for the quick responses and the swift resolution and clarification! 🥇

New doc proposal for: https://netbasal.gitbook.io/spectator/components/untitled-1 (Mock Components).

Mock Components

Sometimes it’s helpful to pass a mock implementation of other components. You can mock components using the ng-mocks library:

import { createHostComponentFactory } from '@netbasal/spectator';
import { MockComponent } from 'ng-mocks';

import { FooComponent } from './path/to/foo.component';

const createHost = createHostComponentFactory({
  component: SettingsPanelComponent,
   declarations: [
     MockComponent(FooComponent)
   ]
 });

For more info about mocking components, please take a look at the ng-mocks docs.