jakerella / jquery-mockjax

The jQuery Mockjax Plugin provides a simple and extremely flexible interface for mocking or simulating ajax requests and responses
Other
2.12k stars 376 forks source link

Getting a fail callback when trying to mock string text reponse for post call #330

Closed juankamilomarin closed 6 years ago

juankamilomarin commented 6 years ago

I have the following real code:

$.ajax({
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    url: "api/method",
    data: JSON.stringify(myData),
    }).then(function (data) {

        //Success code
        //Get the text that I need
        myText = data.toString();

    }, function (data) {

        //Fail code
    });

This is the mocking code:

    $.mockjax({
        url: "api/method",
        type: "POST",
        dataType: "json",
        contentType: "application/json",
        response: function () {
            this.responseText = "Fake response text";
            this.contentType = "application/json";
            this.status = 200;
        }
    });

A real request and response header have content-type = application/json and the response is success (yes, despite the fact that the response is a string), leading the code to the success piece of code in the then() function. However, when doing the mock the response is a fail and the fail block is the one that's executing.

If I try this, it works:

    $.mockjax({
        url: "api/method",
        type: "POST",
        dataType: "json",
        contentType: "application/json",
        response: function () {
            this.responseText =  { "fakeText": "Fake response text" };
            this.contentType = "application/json";
            this.status = 200;
        }
    });

However, I can't assert later the code since data.toString() returns [Object object]. I can mock also Object.prototype.toString but I don't know if that's the real solution.

Thanks in advance for any help!

travstone commented 6 years ago

I don't think I've used the jQuery ajax method that way before (if the code snippet is accurate); usually I've seen it as $.ajax(request stuff).done(success stuff}).fail(error stuff).always(etc). I'm not sure if that's a problem.

Regarding the error, it looks like you're specifying JSON for the response type, so if you return a string I'm pretty sure jQuery thinks that's an error in the response, hence it fires the fail code. I think you basically established that with your final snippet.

I'm not sure what you mean by that last line... what does 'assert later the code' mean?

juankamilomarin commented 6 years ago

By that I mean asserting this piece of code:

myText = data.toString();

I know I'm expecting JSON from the response type, however, when calling the real API I does work (even though the response is a string) and it does execute success call

jakerella commented 6 years ago

jQuery goes into failure handlers on Ajax calls that respond with data that doesn't match the dataType. This is exactly how it is expected to behave. My guess is that your server is in fact returning JSON data, even if it doesn't quite look like it. For example, a string with quote ("some stuff") is in fact valid JSON. However, you're mocked response of Fake response text is NOT JSON.

You could change your response to something like this:

response: function () { this.responseText = "\"Fake response text\""; // notice the escaped quotes this.contentType = "application/json"; this.status = 200; }

But really, if you're expecting JSON, return JSON. If you need to evaluate the string version of that, you can use JSON.stringify(data), but that isn't a great way to do assertions. In any case, this isn't a bug in Mockjax, so I'm going to close the issue. Hopefully the above example works for you.

juankamilomarin commented 6 years ago

Thank you @jakerella

That was the issue (escaping the quotes)