简体   繁体   中英

How do I unit test an angular component that subscribes to an EventEmitter from a service?

I have a component that looks like this:

export class MyComponent {
    myattr: boolean = true;
    constructor(public myService: MyService) {
        this.myService.stateUpdate.subscribe((event: number) => {
            this.myattr = event == 10;
        });
    }

the service:

export class MyService {
    stateUpdate: EventEmitter<number> = new EventEmitter<number>();
    onSomeEvent(): void {
        this.stateUpdate.emit(130);
    }
}

my attempt at unit testing:

    beforeEach(() => {
        fixture = TestBed.createComponent(MyComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
        component.myService = new MyService();
    });
    it("emitting 130 should set myattr to false", async()=>{
        component.myService.stateUpdate.subscribe((event: number) => {
            expect(event).toEqual(130); // this is detected correctly
        })
        component.myService.onSomeEvent();
        fixture.whenStable();
        expect(component.myattr).toEqual(false); // this does not work
    });

Basically, I want to test what happens when whatever code inside subscribe finishes executing. How do I do this?

Thanks

In your example you create service and assign it to myService property after component is already created, so subscription in constructor is made on another instance of service. You can create instance of service or create mock of it inside test file and provide it by MyService token when you are configuring testbed. So you can later have access to that instance and emit event on it

You have to do your assertion inside fixture.whenStable().then()

it("emitting 130 should set myattr to false", async(()=>{
    component.myService.onSomeEvent();
    fixture.whenStable().then(() => {
        expect(component.myattr).toEqual(false);
    });
});

Note that Angular's async() is being replaced with waitForAsync()

In the Angular official docs there is a whole section for common testing scenarios that may be helpful:

https://angular.io/guide/testing-components-scenarios

In your particular case, give a look to these two subsections for a complete explanation with examples:

https://angular.io/guide/testing-components-scenarios#component-with-a-dependency

https://angular.io/guide/testing-components-scenarios#component-with-async-service

There are different approaches, but what I usually do is provide a service stub with a test subject to emit values and then in the test case use the async keyword so I can expect the results when emitted.

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