Skip to content
Advertisement

Unit test a method called from a method

I have an angular application and a method that gets provoked on click. In this method I am passing a value to another private method.

.ts file

public onViewItem(item: Results): void {
    const ids = [item.data['id']];
    this.anotherMethod(ids);
}

.spec file

it('should trigger a method on view item', () => {
    component.onViewItem(documents[0]);
    expect(component.onViewItem).toHaveBeenCalled();
});

How do I test the line const ids = [item.data['id']]; and check the call of this.anotherMethod(ids);

Answer

There is a good practice for it: check the expected results and avoid checking which method is being called in between. It would make the test easy to maintain.

Let’s explore it with an example.

public onViewItem(item: Results): void {
    const ids = [item.data['id']];
    this.anotherMethod(ids);
}
public anotherMethod(ids: number[]): void {
    this.ids = ids;
}

What are the options to test it? I see two:

Bad one

Spy on the anotherMethod:

it('should trigger a method on view item', () => {
    spyOn(NameOfTheComponent, 'anotherMethod')
    
    component.onViewItem(documents[0]);

    expect(component.anotherMethod).toHaveBeenCalledWith([documents[0].id]);
});

Good one

Test the expected results:

it('should trigger a method on view item', () => {
    spyOn(NameOfTheComponent, 'anotherMethod')
    
    component.onViewItem(documents[0]);

    expect(component.ids).toEqual([documents[0].id]);
});

Why is the good one better? Consider you refactored the onViewItem method. Now it looks like this:

public onViewItem(item: Results): void {
    const ids = [item.data['id']];
    this.ids = ids;
}

The arguments are the same. Results yielded by the method execution exactly the same as well. if you had a spy on the function you are forced to refactor the test. If you just tested the expected results – you are good to go.

Advertisement