Error on Jasmine - Expected event click to have be

2019-02-20 02:46发布

问题:

I am referred this link to trigger a event when developing a testing tool in Jasmine framework:

http://www.htmlgoodies.com/beyond/javascript/js-ref/testing-dom-events-using-jquery-and-jasmine-2.0.html

I am trying to get the newly applied CSS attribute after triggering a click event on #DIV_ID in Jasmine framework.

I am tried this code:

 spyEvent = spyOnEvent('#DIV_ID', 'click');
 $('#DIV_ID').trigger( "click" );
 expect('click').toHaveBeenTriggeredOn('#DIV_ID');
 expect(spyEvent).toHaveBeenTriggered();

But I am getting the error: Expected event click to have been triggered on #DIV_ID

Anyone help me to resolve my problem.

Thanks in advance.

回答1:

There is some syntax error in your code:

 var spyEvent = spyOnEvent($('#DIV_ID'), 'click');
 $('#DIV_ID').trigger( "click" );
 expect('click').toHaveBeenTriggeredOn($('#DIV_ID'));
 expect(spyEvent).toHaveBeenTriggered();

I hope this works.



回答2:

I have had the same problem. In my case it seems to be related to have loaded two different versions of JQuery, the one that is used internally by jasmine-jquery (and its matchers and assertions) and the one used by my system under test.

In my case putting this code in a Jasmine test:

    setFixtures('<a id="hello"></a>');
    var spyEvent = spyOnEvent('#hello', 'click');
    $('#hello').trigger('click');
    expect(spyEvent).toHaveBeenTriggered();

makes the assertion fail. The problem seems to be that "$" does not references the version of jQuery used by jasmine-jquery's "spyOnEvent". If you change "$" into "$j" to trigger the event, the event is captured and the assertion succeeds:

    setFixtures('<a id="hello"></a>');
    var spyEvent = spyOnEvent('#hello', 'click');
    $j('#hello').trigger('click');
    expect(spyEvent).toHaveBeenTriggered();

The problem is that if you register event handlers in your code under test with "$" they will not be executed when the events are triggered with "$j". So, if you execute the following code:

    setFixtures('<a id="hello"></a>');
    $('#hello').on('click', function () { console.log("CLICK EVENT"); });
    var spyEvent = spyOnEvent('#hello', 'click');
    $j('#hello').trigger('click');
    expect(spyEvent).toHaveBeenTriggered();

, no message will be printed on the console. Obviously, if you change the "$.on" by a "$j.on" the message will be shown.

What is even more interesting is that, if you change the fixture into a "button" and you try to test the triggering of its click event, the two versions of "$" and "$j" will be perfectly compatible. That is, the code:

    setFixtures('<button id="hello"></button>');
    $('#hello').on('click', function () { console.log("CLICK EVENT"); });
    var spyEvent = spyOnEvent('#hello', 'click');
    $j('#hello').trigger('click');
    expect(spyEvent).toHaveBeenTriggered();

will work perfectly with its assertion being true and the 'click' handler executing, even if you register the handler with "$j" instead of "$", or trigger the event with "$" instead of "$J", or change them in any combination you want.

Finally, another solution that seems to work and its more simple is to use the jquery-simulate library as explained in How can I mimic a native browser event. This code only changes ".trigger" by ".simulate":

    setFixtures('<a id="hello"></a>');
    $('#hello').on('click', function () { console.log("CLICK EVENT"); });
    var spyEvent = spyOnEvent('#hello', 'click');
    $('#hello').simulate('click');
    expect(spyEvent).toHaveBeenTriggered();

, and works perfectly. The ".simulate" method must be called on a "$" object because the library is injected into "$"'s jQuery version in my case. On the contrary ".on" handler registration could be called over a "$" or "$j" with the same behaviour. Moreover, the ".simulate" method allows you to simulate "native browser events" that jQuery alone can't.