How can I keep track of an item?

Let's say I have this directive:

.directive 'panelcreator', ->
    (scope, element)->
        element.bind 'mouseenter', ->
            element.addClass 'alert alert-danger'

      

To keep this unit spec, I want to stub element.addClass

, right? So how can I do this?

My attempt:

describe 'panelcreator', ->

    describe 'something', ->
        beforeEach ->
            spyOn(element, 'addClass')
            element.trigger('mouseenter')

        it 'shoud create a panel', ->
            expect(element.addClass).toHaveBeenCalledWith 'alert alert-danger'      

      

Gives me:

Error: Expected a spy, but got Function.

      

How will I parse the type variable element

in the future so I can find out the chain of methods that I need to pass SpyOn

?

+3


source to share


3 answers


When using jQuery addClass

will reside in a jQuery object:

spyOn($.fn, 'addClass');

      



If not, it will be on the jqLite object (angular.element):

spyOn(angular.element, 'addClass');

      

+1


source


You don't need to stub addClass

to "keep it in the unit spec", there is nothing wrong with using it real Element

.

Interrupting the method is useful when testing the use of some discrete interface with one access point. DOM elements, however, are complex data structures with (usually) more than one way to perform a specific action. If you were to check that your function is adding an element to Array

, you wouldn't want to stub .push()

either
(as there are many other ways to add an element). So, when testing DOM interaction, you can simply add DOM elements to the "utility" list that you are allowed to use (instead of knocking).

When checking if a class is added, just check for it.




Please note that this invalidates your bonus question. To make this absolutely clear in general terms:

Yes, you can check the source code jqLite

(perhaps by going through the call addClass

) and find out that you need to observe the real Element

, not the packaging of it angular.element()

. This way you can try dimming Element.classList.add()

.

However, the entire previous paragraph is irrelevant. Stubbing is only suitable when you need to test the use of an object without having to provide an implementation and / or rely on it. Both Element

and its wrapper jqLite

are guaranteed to be compatible with the primary functions, and their implementation is implicitly provided since your code runs in a web browser and uses AngularJS. This makes any of them counterproductive.

+1


source


You tried

spyOn(element.prototype, 'addClass')

?

and then

expect(element.prototype.addClass).toHaveBeenCalledWith 'alert alert-danger'

0


source







All Articles