apollographql / fullstack-tutorial

🚀 The Apollo platform tutorial app
https://www.apollographql.com/docs/tutorial/introduction.html
MIT License
1.24k stars 842 forks source link

Integration Tests Not Properly Mocked #90

Open mikecfisher opened 5 years ago

mikecfisher commented 5 years ago

I followed the integration tests example pattern in my own app.

   // mock the datasources' underlying fetch methods, whether that's a REST
    // lookup in the RESTDataSource or the store query in the Sequelize datasource
    launchAPI.get = jest.fn(() => [mockLaunchResponse]);

However I noticed it was still making api calls to the rest endpoint. I then cloned this repo turned off my wifi and ran the integration tests and sure enough I got an error.

errors": Array [
    +     Object {
    +       "extensions": Object {
    +         "code": "INTERNAL_SERVER_ERROR",
    +         "exception": Object {
    +           "code": "ENOTFOUND",
    +           "errno": "ENOTFOUND",
    +           "message": "request to https://api.spacexdata.com/v2/launches?flight_number=30 failed, reason: getaddrinfo ENOTFOUND api.spacexdata.com api.spacexdata.com:443",
    +           "type": "system",
    +         },
            },
    -       "rocket": Object {
    -         "type": "FT",
    -       },
    +       "locations": Array [
    +         Object {
    +           "column": 3,
    +           "line": 2,
    +         },
    +       ],
    +       "message": "request to https://api.spacexdata.com/v2/launches?flight_number=30 failed, reason: getaddrinfo ENOTFOUND api.spacexdata.com api.spacexdata.com:443",
    +       "path": Array [
    +         "launch",
    +       ],

This tells me that launchAPI.get is not being properly mocked. Which I think would make sense as there is no launchAPI.get however there is a launchAPI.prototype.get however that doesn't seem to work when I change the tests to that.

Any ideas?

mikecfisher commented 5 years ago

Ok I was able to properly mock it by doing this.

describe("Queries", () => {
  it("fetches an author stream header", async () => {
    // create an instance of ApolloServer, while reusing
    // existing dataSources, resolvers, and typeDefs.
    // This function returns the server instance as well as our dataSource
    // instances, so we can overwrite the underlying fetchers
    // APIDataSource is an uninvoked class instance
    const { server, APIDataSource } = constructTestServer();

    // mock the datasources' underlying fetch methods
    APIDataSource.prototype.get = jest.fn(() => mockServerAuthorResponse);

    // use our test server as input to the createTestClient fn
    // This will give us an interface, similar to apolloClient.query
    // to run queries against our instance of ApolloServer
    const { query } = createTestClient(server);
    const res = await query({
      query: GET_AUTHOR,
      variables: { username: "amy87" },
    });
    expect(res).toMatchSnapshot();
  });
});
basicBrogrammer commented 4 years ago

Why not use something like https://github.com/aexmachina/factory-girl ? mocking calls to the database for an integration tests or even testing the resolvers seems like a red flag. What if the queries in the UserAPI aren't right? And then if the User model is changed you have to change the mock everywhere.