fullstack-tutorial icon indicating copy to clipboard operation
fullstack-tutorial copied to clipboard

Integration Tests Not Properly Mocked

Open mikecfisher opened this issue 5 years ago • 2 comments

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 avatar Jun 21 '19 16:06 mikecfisher

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();
  });
});

mikecfisher avatar Jun 21 '19 21:06 mikecfisher

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.

basicBrogrammer avatar Sep 28 '19 10:09 basicBrogrammer