1

I have the following method to load a JSON file using coffeescript/jquery:

Class JsonParser

this.return  = (json_file_path, string_to_query) ->
  $.getJSON json_file_path, (data) ->
    $.each data, (key,val) ->
     if key == string_to_query
       return val

And I am Testing it in Jasmine with:

expect(JsonParser.return("file.json", "key").toEqual("value")

But what Jasmine spits out instead is:

Expected { readyState : 1, getResponseHeader : Function, getAllResponseHeaders
 : Function, setRequestHeader : Function, overrideMimeType : Function, statusCode : Function, abort : 
Function, state : Function, always : Function, then : Function, promise : Function, pipe : Function, d
one : Function, fail : Function, progress : Function, complete : Function, success : Function, error :
 Function } to equal 'value'.

Assume the JSON file has only one line: { "key": "value" }

I am just getting my feet wet with jquery/coffeescript/ajax etc. and don't understand Jasmines response. Let me know if further information is needed thanks!.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
Discorick
  • 1,546
  • 2
  • 10
  • 15

1 Answers1

2

Your problem is that your return method doesn't return what you think it does. Your return function returns what getJSON returns and getJSON is an AJAX call. jQuery's AJAX calls all return jqXHRs and that has nothing to do with what the AJAX callbacks return. The sequence of events looks something like this:

  1. You call JsonParser.return.
  2. return calls $.getJSON.
  3. getJSON makes an asynchronous call to the server and then returns a jqXHR.
  4. return returns the same jqXHR that getJSON returns.
  5. Some time passes.
  6. The server gets around to responding and your callback is called to search through the JSON.

The problem is that while (5) is happening, the code that called JsonParser.return is still going but it has no JSON.

The usual way to get around the asynchronous nature of AJAX calls is to send in a callback function that will get called when something is ready:

@return: (json_file_path, string_to_query, callback) ->
  $.getJSON json_file_path, (data) ->
    $.each data, (key,val) ->
     if key == string_to_query
       callback(val)

Then you'd use it like this:

JsonParser.return("file.json", "key", (value) ->
  # Do whatever needs to be done with value in here.
)

Now you have something that should work and you can find out how to use Jasmine with it over here:

How do I verify jQuery AJAX events with Jasmine?

Community
  • 1
  • 1
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • Thanks for the response, I am still getting the same result, the json file path I have been using is a local file, not called through a server, is that potentially an issue ? – Discorick Apr 25 '13 at 18:48
  • @Discorick: You can't do AJAX without a server and you can't use normal Jasmine techniques to test AJAX. – mu is too short Apr 25 '13 at 19:01