1

Running this unit test in Angular 21 always fails with the following error:

× should toggle showSettings when settings button is clicked (440231 ms) ● DrawerComponent › should launch settings modal when button is clicked expect(jest.fn()).toHaveBeenCalled() Expected number of calls: >= 1 Received number of calls: 0 

it('should launch the Settings modal when button is clicked', () => { const settingSpy = jest.spyOn(component as any, 'showSettings'); const buttons = fixture.debugElement.queryAll(By.directive(ButtonComponent)); buttons[4].triggerEventHandler('click', null); fixture.detectChanges(); expect(settingSpy).toHaveBeenCalled(); });

Note: The buttons array (of type DebugElement[]) returns 7 instances of ButtonComponent.

The "Settings" button I'm interested in is actually in index position 4, yet my click event still doesn't work. i.e. The expected num of calls should be "1".

Here's a snippet of the component's template (fyi: is part of our custom UI library) :

<div class="menu-settings"> <div class="divider"></div> <div class="app-controls"> <my-button icon="settings" (buttonClick)="showSettings()" > </my-button> <my-button icon="info" (buttonClick)="showAboutModal()" ></my-button> </div> </div>

In the DOM, expands to this HTML:

<my-button _ngcontent-ng-c1665131262="" icon="info" variant="flat" iconposition="end"> <button class="my-button my-button--basic my-button--medium my-button--flat my-button--icon my-button--icon-end tpcn-typography-button" id="null" type="button"> <div class="my-button-surface"></div> <div class="my-button-state my-button-hover"></div> <div class="my-button-state my-button-pressed"></div> <div class="my-button-state my-button-selected"></div> <div class="my-button-state my-button-focus"></div> <div class="my-button-content"><!--container--><!--container--><!--container--><!--container--><tpcn-icon class="my-button-icon" _nghost-ng-c2485891322=""> <div _ngcontent-ng-c2485891322="" svgicon="" class="tpcn-icon"><svg fill="currentColor" viewBox="0 0 24 24"> <path fill="none" d="M0 0h24v24H0V0z"></path> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 15c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1zm0-8c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"> </path> </svg></div><!--container--><!--container--> </tpcn-icon><!--container--> </div> </button> </my-button>

Questions:

  1. How do I make this work ?
  2. How can I look up my settings button in that array, via settingsButtons.find() ?

** UPDATE** This ended up working for us. We ended up using the .app-controls class which wrapped our custom buttons.

it('should toggle showSettings when settings button is clicked', () => { const settingSpy = jest.spyOn(component as any, 'showSettings'); const buttons = fixture.debugElement.queryAll(By.css('.app-controls button')); buttons[0].triggerEventHandler('click', null); fixture.detectChanges(); expect(settingSpy).toHaveBeenCalled(); });

1
  • 1
    please share the contents of my-button, html and ts code Commented Nov 6 at 17:09

1 Answer 1

1

You are clicking the actual component, which will not do anything, you need to query for the button whose (click) event triggers the buttonClick event emitter.

The selector can be changed to:

fixture.debugElement.queryAll(By.css('.app-controls button')); ... buttons[0].triggerEventHandler('click', null); 
Sign up to request clarification or add additional context in comments.

4 Comments

But fixture.debugElement.queryAll(By.directive(ButtonComponent)) returns a type of DebugElement[] (which has the triggerEventHandler and other DOM properties on it). So I thought it would be clickable, just like the other tests which use By.css() .
it turns out that we accessed that button with fixture.debugElement.queryAll(By.css('.app-controls button')); - since at the end of the day our custom ButtonComponent renders a standard <button>. The click event also worked (buttons[0].triggerEventHandler('click', null);), and the spy was successful.
great! updated my answer
then you got it ! Hopefully someone else will benefit as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.