Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

accessorSpies in jest-auto-spies + nx workspace not mocking return value #42

Open
GuilleEneas opened this issue Feb 10, 2021 · 17 comments

Comments

@GuilleEneas
Copy link
Contributor

Describe the bug
When creating a service with a getter and trying to mock it in a test the returned value is undefined.

To Reproduce
Steps to reproduce the behavior:

  1. npx create-nx-workspace
  2. cd to your project
  3. nx g s --name=one --project=app --skipTests
  4. then check the changes in this commit
  5. ng test --watch

and boom

 FAIL  apps/app/src/app/app.component.spec.ts
  ● AppComponent › whatever

    expect(received).toStrictEqual(expected) // deep equality

    Expected: {"fake": "value"}
    Received: undefined

      32 |     const value = componentUnderTest.getGetter();
      33 |
    > 34 |     expect(value).toStrictEqual({
         |                   ^
      35 |       fake: 'value'
      36 |     });
      37 |   });

      at src/app/app.component.spec.ts:34:19
      at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (../../node_modules/zone.js/dist/zone.js:386:30)
      at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (../../node_modules/zone.js/dist/proxy.js:117:43)
      at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (../../node_modules/zone.js/dist/zone.js:385:36)
      at Zone.Object.<anonymous>.Zone.run (../../node_modules/zone.js/dist/zone.js:143:47)

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        3.522s

Expected behavior
the test should pass

Desktop (please complete the following information):

  • OS: Mac OSX
  • Browser chrome
  • Version 88.0.4324.146

You can also clone this repo where the issue occurs https://github.com/GuilleEneas/jest-auto-spies-issue

@GuilleEneas
Copy link
Contributor Author

GuilleEneas commented Feb 10, 2021

I checked a bit and the returned object from provideAutoSpy method contains the getter, while after calling TestBed.inject the returned object has the getters striped out.

@shairez
Copy link
Member

shairez commented Feb 11, 2021

Thanks @GuilleEneas !

Sometimes Jest has weird issues with it's caching, did you try cleaning it's cache and run it again?

@GuilleEneas
Copy link
Contributor Author

Hi @shairez !

Yes, I did. As I mention before, the method provideAutoSpy seems to work as expected, is the interaction with the test bed injector the one that seems to remove the getters and setters, but keeps the accessorSpies.

@shairez
Copy link
Member

shairez commented Feb 16, 2021

Really weird issue, without debugging I was able to simulate the issue

But when debugging it step by step... I was able to pass the test and see the getters on OneService

WTF 😀

image

@shairez
Copy link
Member

shairez commented Feb 16, 2021

It might have something to do with the fact that I made a small change to AppComponent (added a method and then removed it).

So I suspect it's an issue with the nx cache or something alike...

@GuilleEneas
Copy link
Contributor Author

this is weird, as when I was debugging step by step the injector returned an object without getters. do you suggest it is a nx bug instead?

@shairez
Copy link
Member

shairez commented Feb 18, 2021

Yeah, the first time I debugged it I saw the issue... but then I changed the file a bit... reverted it (but because it was "changed" the timestamp was different I guess) and then I couldn't reproduce anymore.

Try that and let me know if that's the case for you as well

if so, it might be the nx cache

@GuilleEneas
Copy link
Contributor Author

I can't make the test pass, even following your steps. I'll try to create this issue with the nx workspace alone to see if this can be an nx issue... do you know if they fix this issues when people submit them. I'll keep you posted 🤓

@shairez
Copy link
Member

shairez commented Feb 23, 2021

Hmm... this is a tricky one.. I guess you'll need to simulate the caching issue in a reproducible way in order for them to fix it

@GuilleEneas
Copy link
Contributor Author

I made some more research, the problem is the Object.defineProperty method, somehow that property got stripped out after being inserted and retrieved from the testbed. I created this repos which reproduces the error https://github.com/GuilleEneas/nx-angular-testing-issue . Could you check it (when having time)?... and please let me know if you think is worth reporting (and if they would be interested in fixing it, in your opinion, ofc)

@shairez
Copy link
Member

shairez commented Feb 24, 2021

Wow... good job finding it!

I'll take a look at it next week and report back

Thanks!

@peterreisz
Copy link

I've also faced with this issue, but in a non-nx project, so I think this issue is not related to nx.

@mtpultz
Copy link

mtpultz commented Mar 1, 2022

I having this issue in an Nx project. I've tried nx test --clearCache in case that helps, but when I spy on a simple service like:

@Injectable({
  providedIn: 'root',
})
export class PartyService {
  private _partyId!: number;

  public set partyId(partyId: number) {
      this._partyId = partyId;
  }

  public get partyId(): number {
    return this._partyId;
  }
}

The value is always undefined:

describe('CollegeLicenceInformationPage', () => {
  let component: CollegeLicenceInformationPage;
  let partyServiceSpy: Spy<PartyService>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        ReactiveFormsModule,
        RouterTestingModule,
      ],
      providers: [
        CollegeLicenceInformationPage,
        {
          provide: PartyService,
          useValue: createSpyFromClass(PartyService, {
            gettersToSpyOn: ['partyId'],
            settersToSpyOn: ['partyId'],
          }),
        },
      ],
    });

    component = TestBed.inject(CollegeLicenceInformationPage);
    partyServiceSpy = TestBed.inject<any>(PartyService);
  });

  describe('INIT', () => {
    given('partyId exists', () => {
      const partyId = randNumber({ min: 1 });
      partyServiceSpy.accessorSpies.setters.partyId.mockReturnValue(partyId);

      when('initializing the page', () => {
        component.ngOnInit();

        then(
          'resource should get the college licence information of the party',
          () => {
            expect(partyServiceSpy.partyId).toBe(partyId); // <--- Always undefined
          }
        );
      });
    });
  });
});

@shairez
Copy link
Member

shairez commented Mar 3, 2022

@GuilleEneas I cannot reproduce the problem from the second run of the tests (only on the first one it fails)
Tried to clear both jest and nx cache but no luck

@peterreisz did it continue to happen?

@mtpultz can you reproduce it consistently and can upload a mini-repo that can show that?

Thanks!

@GuilleEneas
Copy link
Contributor Author

@shairez I need to check, this was long ago, I might remember that this wasn't happening when updating nx. I'll check in the following days. just to be clear did you check this repo https://github.com/GuilleEneas/nx-angular-testing-issue?

@shairez
Copy link
Member

shairez commented Mar 3, 2022

@GuilleEneas yep

Btw with a brand new nx I couldn't reproduce

@mtpultz
Copy link

mtpultz commented Mar 10, 2022

@shairez I created a new install of Nx, and was able to quickly reproduce it using a barebones Angular application- https://github.com/mtpultz/jest-auto-spies-error. When you run nx test you see a similar error to the one posted above.

UPDATE: Sorry @shairez looks like I had a typo and was using setters in my statement bonnieServiceSpy.accessorSpies.setters.bonnieId.mockReturnValue(bonnieId); instead of getters bonnieServiceSpy.accessorSpies.getters.bonnieId.mockReturnValue(bonnieId); when using mockReturnValue(...) :(

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

No branches or pull requests

5 participants
@mtpultz @shairez @GuilleEneas @peterreisz and others