Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

reproduce failure case in integration test #153

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kamleshchandnani
Copy link

@kamleshchandnani kamleshchandnani commented Jul 8, 2020

Basically the problem is that when one of our datasource methods triggers an error then the errorFromResponse method is called and then the error is returned and we see that error in our playground but when you try to test it and mock the error in your test the error you get from query/mutation method from apollo-server-testing are both different.

In this PR to reproduce this issue what I've done is I changed the endpoint of spaceX and made it point to launch instead of launches which doesn't exist so the datasource method will get triggered and then I've overwritten errorFromResponse to handle the errors and what I'm doing there is I'm sending a ApolloError with custom message.

Now when you open it in playground and run the query getLaunchById it'll throw the error and the error object looks something like this

{
  "errors": [
    {
      "message": "NOT_FOUND",
      "locations": [
        {
          "line": 13,
          "column": 3
        }
      ],
      "path": ["launch"],
      "extensions": {
        "code": "Not Found",
        "response": {
          "url": "https://api.spacexdata.com/v2/launch?flight_number=123",
          "status": 404,
          "statusText": "Not Found",
          "body": "Not Found"
        },
        "exception": {
          "stacktrace": [
            "Error: NOT_FOUND",
            "    at LaunchAPI.errorFromResponse (/Users/kamlesh/razorpay/fullstack-tutorial/final/server/src/datasources/launch.js:53:15)",
            "    at processTicksAndRejections (internal/process/task_queues.js:93:5)"
          ]
        }
      }
    }
  ],
  "data": {
    "launch": null
  }
}

Now I want to test this and assert that my error object is same as one returned when I actually run this query. So what I did was in my test I just mock the datasource get method and reject it's value with Not Found here at this line but now when I execute my query inside the test the response object returned(which is error object) inside my test is this

{
  "http": {
    "headers": {}
  },
  "errors": [
    {
      "message": "Unexpected error value: \"Not Found\"",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": ["launch"],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR"
      }
    }
  ],
  "data": {
    "launch": null
  }
}

and when I do
expect(res).toEqual(errorFromPlayground); it fails because obviously the two objects are different. Now the question is why are these objects different and how do I make this assertion pass?

Reproduces #154

@apollo-cla
Copy link

@kamleshchandnani: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/

@kamleshchandnani
Copy link
Author

@stemmlerjs @JakeDawkins @hwillson If you can provide some inputs on this?

@JakeDawkins
Copy link
Contributor

So it looks like the reason the errorFromResponse function isn't being called is because you're overwriting the get function. In the implementation of the RESTDataSource, get calls this.fetch, which which calls the didReceiveResponse handler, which calls errorFromResponse. So since you're mocking get, none of that chain gets called.

@JakeDawkins
Copy link
Contributor

I don't think this is a bug, but rather just a difficult thing to mock. I'd have to do a little more investigation to figure out a clear story for mocking this, but I don't think I have time anytime soon to dig into that

@kamleshchandnani
Copy link
Author

kamleshchandnani commented Jul 9, 2020

@JakeDawkins Ah okay. I tried to mock the underlying fetch but seems like it's not trivial and I didn't had any luck to make it work 😓

The problem is I can't really mock the underlying fetch because it's jut not the fetch there's more stuff going in there inside the RESTDataSource.ts like HTTPCache and stuff.

@kamleshchandnani
Copy link
Author

@stemmlerjs @JakeDawkins @hwillson can anyone of you help with any other alternative way of achieving this?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants