Last Updated: September 09, 2019
·
10.26K
· alexmreis

Testing AngularJS radio buttons using Karma and Jasmine

I've struggled for months on how to correctly trigger the right event to make angular pick up a click on a radio button and update the scope accordingly.

Usually you have something like:

<input type="radio" 
       id="myPropertyTrue"
       name="myProperty"
       ng-value="true"
       ng-model="myModel.myProperty"/>
<input type="radio" 
       id="myPropertyFalse"
       name="myProperty"
       ng-value="false"
       ng-model="myModel.myProperty"/>

<div class="extraFormControls"
     ng-if="myProperty">
    ... dependent form controls ...
</div>

And you would think on your Jasmine test something like this would suffice:

describe 'my page', ->
  describe 'when myProperty is true', ->
    beforeEach ->
      $('myPropertyTrue').click()
     it 'shows extra form controls', ->
       expect($('.extraFormControls')).toExist()

But it won't work. The ng-if is not updated. One might think it's due to the scope not updating, but that is actually not the case. The problem is jQuery's .click() does not trigger the 'click' event.

You should do:

beforeEach ->
  $('myPropertyTrue').click().trigger('click')

And that works every time. I hope this helps you since I lost almost 2 work days looking for a solution.

I tried everything from an async loop repeatedly clicking the radio to triggering focus, blur, mousedown, mouseup, change, input, selected, but nothing worked. A bit counterintuitive, but once you've got it in your toolbox, it's certainly not rocket science.

Follow me on twitter: @alexmreis

2 Responses
Add your response

$('myPropertyTrue').triggerHandler('click'); does the trick too

over 1 year ago ·

Thank you. Was stuck on this all evening. Calling click().click() works too, or whatever you choose to make the click happen, it just seems to matter that you do it twice. Remember to add a comment so nobody undoes this silly code.

over 1 year ago ·