hirezio / auto-spies

Create automatic spies from classes
MIT License
181 stars 30 forks source link

Spying on observable property getter is failing #40

Closed ts46235 closed 3 years ago

ts46235 commented 3 years ago

Describe the bug While following the example at https://www.npmjs.com/package/jasmine-auto-spies?activeTab=readme#-spying-on-observable-properties, I did created a spy for the userData$ observable property of the OidcSecurityService of angular-auth-oidc-client.

I set up the spy like the example and attempted to set up the nextWith and got the error nextWith is not a function

I have stepped thru the code and at https://github.com/hirezio/auto-spies/blob/master/packages/auto-spies-core/src/create-auto-spy-from-class.ts line 74 before the methodNames are iterated, the spy behaves correctly and it begins to fail after the method names are iterated and it appears to be caused because the observable property, userData$ is contained in the methodNames variable and so it is overwriting the property set up that occurred on line 68: autoSpy[observablePropName] = createObservablePropSpy();

To Reproduce Steps to reproduce the behavior:

  1. Create a class that depends on OidcSecurityService from angular-auth-oidc-client

  2. Create a jasmine unit test for the class that setups the spy like so:

    const oidcSecurityServiceSpy = createSpyFromClass(OidcSecurityService, {
      observablePropsToSpyOn: ['userData$']
    });
    oidcSecurityServiceSpy.userData$.nextWith({
      preferred_username: 'fakeUser'
    });
  3. Run the test and see the error "oidcSecurityServiceSpy.userData$.nextWith is not a function''

Expected behavior No error when try to assign nextWith result

Desktop (please complete the following information):

Additional context My workaround is to re-assign the prop spy after the call to createSpyFromClass by re-using the same code that is used to set it previously on line 68: autoSpy[observablePropName] = createObservablePropSpy();

It seems the problem lies in the population of methodNames. Using Object.getOwnPropertyNames will retrieve these observable property getters along with all the function properties. Instead you could use getOwnPropertyDescriptors and use that to only retrieve the functions or else find the ones that are getters so they can be removed.

GuilleEneas commented 3 years ago

thank you @ts46235 for your detailed description 😄

batbrain9392 commented 3 years ago

@shairez I was mentioning problems with NGXS selectors. I think it's this fix that solved it.