robodisco
robodisco

Reputation: 4272

How to use Jasmine to spy on methods within a jquery plugin

I have a plugin defined as such

(function($){


    $.fn.robodisco = function(callerSettings) {

        var findVideos = function(params){ ... }

        $(".track").click(function(){
            ....
            findVideos(data) });

        ....

And in my test I want to spy on the findVideos and check if it is called. Jasmine however keeps complaining it can't find the method. Here is my spec:

it("searches for videos for track", function(){
      spyOn($.fn.robodisco, "findVideos");
      $lastTrack.click();
      expect($.fn.robodisco.findVideos).toHaveBeenCalled();
});

Is my syntax wrong?

Upvotes: 4

Views: 2246

Answers (2)

Nevy
Nevy

Reputation: 31

I know this is an older post, but I thought I would answer as I found a solution that helped me with the same issue today. I have a jasmine unit test that ensures the dcjqaccordion plugin is initialized with a certain set of defaults inside an AngularJS Provider that wraps the accordion plugin. What I did was I mocked the element I passed to the plugin with a spy that stubs the function of the expected plugin call.

Test code:

var mockElement = jasmine.createSpyObj('mockElement', ['dcAccordion']);

it('should initialize with prescribed defaults', function(){

        var expectedDefaults = {
            eventType: 'click',
            autoClose: false,
            saveState: true,
            disableLink: true,
            speed: 'slow',
            showCount: false,
            autoExpand: true,
            classExpand: 'dcjq-current-parent'
        };

        testDcjqaccordionProvider.initialize(mockElement);

        expect(mockElement.dcAccordion).toHaveBeenCalledWith(expectedDefaults);

    });

Production code:

app.provider('dcjqaccordionWrapper', function(){

    //Lazy load our dependency on the plugin
    function getAccordionPlugin(){
        $.getScript('scripts/jquery.dcjqaccordion.2.7.js')
            .done(function(){
                console.log("Successfully loaded the dcjqaccordion plugin.");
            })
            .fail(function(){
                console.log("There was a problem loading the dcjqaccordion plugin.");
            });
    }


    var defaults = {
        eventType: 'click',
        autoClose: false,
        saveState: true,
        disableLink: true,
        speed: 'slow',
        showCount: false,
        autoExpand: true,
        classExpand: 'dcjq-current-parent'
    };

    this.initialize = function(inElement){
      inElement.dcAccordion(defaults);
    };

    this.$get = function(){
        getAccordionPlugin();
        return this;
    };
})

Upvotes: 2

vaxinate
vaxinate

Reputation: 11

The problem is that you're looking for findVideos to be a property of the robodisco method which it is not. It's a local variable within that method, so trying to access it via robodisco.findVideos isn't going to work.

I don't really have a fix for you as I'm having a similar problem and am currently researching how to solve it. The methods I am trying to spy on are defined outside of the namespace of my jQuery plugin as recommended the plugin authoring docs.

I'll update if i find a solution. I can't find much and I'm thinking that it won't be possible for me to grab my methods since they're wrapped in an anonymous function call, but we'll see.

Upvotes: 1

Related Questions