pabera
pabera

Reputation: 1042

Jasmine testing Backbone, Scoping trouble

I really got an annoying error when writing jasmine tests for one of my current backbone collections and I think it's not the way I write the test instead of doing something wrong in my javascript and jasmine wants to tell me that. But I can't find a solution.

I got the following simplified code which will lead us to the problem

class Stuff extends Backbone.Collection
    search: (str) ->
        @trigger('search', @_filter(@_convertStrToArray(str)))

    _convertStrToArray: (str) ->
        str.toLowerCase().split()

    _filter: (str_array) ->
        @filter (stuff) ->
            for _sub in str_array
                ... do something here

I would like to test with jasmine, if the @_convertStrToArray method has been called on executing @search. I got the following test (@stuff has been successfully created in a beforeEach statement!)

...
it "should call _convertStrToArray", ->
    spyOn(@stuff, '_convertStrToArray')
    @stuff.search('cool stuff')
    expect(@stuff._convertStrToArray).toHaveBeenCalled()
...

I am getting the following error in my jasmine test now..

TypeError: Cannot read property 'length' of undefined

By tracking down the stacktrace I found out that the error comes from the following line:

for _sub in str_array

Obviously there is a scoping problem here I am not able to solve. The @filter method in the _filter method comes from Backbone. The script works absolutely fine, I am just having trouble with the test.

My question: How can I correctly gain access on the str_array variable in the @filter call?

Upvotes: 0

Views: 610

Answers (1)

Derick Bailey
Derick Bailey

Reputation: 72868

the problem is your spy. The for _sub in str_array is using an index / length check to iterate, but the spied on _convertStrToArray doesn't return any value.

You need to add .andCallThrough() to the end of your spy definition:

spyOn(@stuff, '_convertStrToArray').andCallThrough()

This will spy on the method, but still call the actual method and it's return value so that your code won't fail when it tries to use the result.

Upvotes: 1

Related Questions