kamilkisiela / apollo-angular

A fully-featured, production ready caching GraphQL client for Angular and every GraphQL server 🎁
https://apollo-angular.com
MIT License
1.5k stars 311 forks source link

Object become empty in flushed object inside test #1624

Closed nerg4l closed 3 years ago

nerg4l commented 3 years ago

Describe the bug

When running tests not empty objects replaced with empty objects. From what I tested it seems the use of an array causes this.

To Reproduce Steps to reproduce the behavior:

Run the test below.

import { TestBed } from '@angular/core/testing';
import {
  ApolloTestingModule,
  ApolloTestingController,
} from 'apollo-angular/testing';
import { Apollo, gql } from 'apollo-angular';

describe('UndefinedSpec', () => {
  let controller: ApolloTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ApolloTestingModule]
    });
    controller = TestBed.inject(ApolloTestingController);
  });

  afterEach(() => {

    // After every test, assert that there are no more pending requests.
    controller.verify();
  });

  it('undefined', (done) => {
    const apollo = TestBed.inject(Apollo);

    const TEST_QUERY = gql`
  query testQuery {
    responseEntity {
      body { ...TestObjFragment }
    }
  }
  fragment TestObjFragment on TestObj {
    id
  }
`;

    apollo.watchQuery({
      query: TEST_QUERY,
    }).valueChanges.subscribe(result => {
      const data = result.data as any;
      expect(data.responseEntity.body[0]).toBeTruthy();
      expect(data.responseEntity.body[0]).not.toEqual({});
      expect(data.responseEntity.body[0].id).toEqual(1);
      done();
    });

    const op = controller.expectOne('testQuery');

    op.flush({
      data: { responseEntity: { body: [ { id: 1, } ], }, },
    });
  });
});

Expected behavior

Test should pass.

Environment:

Additional context

The same definition works just fine in the browser.

nerg4l commented 3 years ago

It seems it has nothing to do with arrays. It is related to fragments. Which makes me think I use the lib incorrectly.

import { TestBed } from '@angular/core/testing';
import {
  ApolloTestingModule,
  ApolloTestingController,
} from 'apollo-angular/testing';
import { Apollo, gql } from 'apollo-angular';

describe('UndefinedSpec', () => {
  let controller: ApolloTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ApolloTestingModule]
    });
    controller = TestBed.inject(ApolloTestingController);
  });

  afterEach(() => {
    // After every test, assert that there are no more pending requests.
    controller.verify();
  });

  it('undefined', (done) => {
    const apollo = TestBed.inject(Apollo);

    const TEST_QUERY = gql`
  query testQuery {
    responseEntity {
      body { ...TestObjFragment }
    }
  }
  fragment TestObjFragment on Entry {
    id
  }
`;

    apollo.watchQuery({
      query: TEST_QUERY,
    }).valueChanges.subscribe(result => {
      const data = result.data as any;
      expect(data.responseEntity.body).toBeTruthy();
      expect(data.responseEntity.body).not.toEqual({});
      expect(data.responseEntity.body.id).toEqual(1);
      done();
    });

    const op = controller.expectOne('testQuery');

    op.flush({
      data: { responseEntity: { body: { id: 1, }, }, },
    });
  });
});
nerg4l commented 3 years ago

My bad I forgot to add __typename.

Maximaximum commented 3 years ago

I've spent about 2 hours debugging the same problem until I found this Github issue 😅

Urigo commented 3 years ago

@Maximaximum do you think there is a place we could add this to the docs to save people time?

Maximaximum commented 3 years ago

@Urigo I believe this page has to be updated: https://apollo-angular.com/docs/development-and-testing/testing/#expecting-and-answering-operations

Strangely enough, even though it contains a sample flush usage, it does not even contain the __typename propery.

Urigo commented 3 years ago

@Maximaximum are you up to creating a Pull Request to the docs?

Maximaximum commented 3 years ago

@Urigo I'd love to, but unfortunately I'm too busy this week