Search code examples
unit-testingjasminekarma-jasminekarma-runner

How can I test the click of a button within an <a> without activating the link


If I have the following:

<a [href]="some-url" target="_blank">
  <button (click)="onClick()">Press me</button>
</a>
function onClick(){
  this.service.doSomething();
}

Using Jasmine/Karma, how can I test that doSomething was called, without opening any link or other unwanted browser behavior? I have tried:

Setting href to empty string and target to _self, which continually refreshes the browser window:

const anchor = fixture.debugElement.query(By.css('a'))?.nativeElement as HTMLAnchorElement;
anchor.href = '';
anchor.target = '_self';

Setting href to # and target to _self, which opens an embedded Karma instance within the browser:

const anchor = fixture.debugElement.query(By.css('a'))?.nativeElement as HTMLAnchorElement;
anchor.href = '#';
anchor.target = '_self';

Returning false from the click handler function, which tests successfully but breaks the app:

function onClick(){
  this.service.doSomething();
  return false;
}

Solution

  • The other answer led me to removing the a href and using a click handler to call window.open instead.

    <button (click)="onClick()">Press me</button>
    
    function onClick(){
      window.open(some-url, '_blank');
      this.service.doSomething();
    }
    
    spyOn(window, 'open'); // prevent new tab being opened
    const button = fixture.debugElement.query(By.css('button'))?.nativeElement as HTMLButtonElement;
    button.click();
    

    This also has the advantage that you can spyOn(window, 'open') to check that the call was made.