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

Unit test: store.reset() has not effect in v3.0.0 #116

Open
XavierDupessey opened this issue Feb 18, 2022 · 6 comments
Open

Unit test: store.reset() has not effect in v3.0.0 #116

XavierDupessey opened this issue Feb 18, 2022 · 6 comments

Comments

@XavierDupessey
Copy link

I'm submitting a...


[x] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => https://github.com/ngxs/store/blob/master/CONTRIBUTING.md
[ ] Other... Please describe:

Current behavior

I updated @ngxs-labs/select-snapshot from 1.2.0 to 3.0.0. I noticed a change in unit tests:

Let's take as an example this very simple component that uses @SelectSnapshot():

// sample.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AccessSelectors } from '@app/shared/access/access.selectors';
import { Access } from '@app/shared/clients/audience-experience-api.client';
import { SelectSnapshot } from '@ngxs-labs/select-snapshot';

@Component({
  template: '',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SampleComponent {
  @SelectSnapshot(AccessSelectors.access) readonly access!: Set<Access>;

  targetMethod(): void {
    if (this.access.has(Access.ViewBudget)) {
      console.log('User has access');
    } else {
      console.log('User has NOT access');
    }
  }
}

And test it:

// sample.component.spec.ts
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { ExceptionService } from '@app/shared/exception/exception.service';
import { ExceptionServiceMock } from '@app/shared/exception/exception.service.mock';
import { NgxsSelectSnapshotModule } from '@ngxs-labs/select-snapshot';
import { NgxsModule, Store } from '@ngxs/store';
import { ngxsConfig } from '@testing/external-dependencies/ngxs-config';
import { noop } from 'lodash';
import { SampleComponent } from './sample.component';
import { AccessState } from './shared/access/access.state';
import { Access } from './shared/clients/audience-experience-api.client';

describe('SampleComponent', () => {
  let component: SampleComponent;
  let store: Store;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [SampleComponent],
      imports: [HttpClientTestingModule, NgxsSelectSnapshotModule, NgxsModule.forRoot([AccessState], ngxsConfig)],
      providers: [{ provide: ExceptionService, useClass: ExceptionServiceMock }],
    });

    component = TestBed.createComponent(SampleComponent).componentInstance;
    store = TestBed.inject(Store);
  });

  afterEach(() => jest.clearAllMocks());

  describe('targetMethod', () => {
    it('should log if access', () => {
      // Arrange
      store.reset({ access: { allAccess: new Set([Access.ViewBudget]) } });
      jest.spyOn(console, 'log').mockImplementation(noop);

      // Act
      component.targetMethod();

      // Assert
      expect(console.log).toHaveBeenCalledTimes(1);
      expect(console.log).toHaveBeenCalledWith('User has access');
    });

    it('should log if NO access', () => {
      // Arrange
      store.reset({ access: { allAccess: new Set() } });
      jest.spyOn(console, 'log').mockImplementation(noop);

      // Act
      component.targetMethod();

      // Assert
      expect(console.log).toHaveBeenCalledTimes(1);
      expect(console.log).toHaveBeenCalledWith('User has NOT access');
    });
  });
});

In the test, I use store.reset() to change the content of the state.

With @ngxs-labs/select-snapshot v1.2.0, the tests pass.
With v3.0.0, they fail:

 FAIL  src/app/sample.component.spec.ts
  SampleComponent
    targetMethod
      √ should log if access (109 ms)
      × should log if NO access (30 ms)

  ● SampleComponent › targetMethod › should log if NO access

    expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: "User has NOT access"
    Received: "User has access"

    Number of calls: 1

      52 |       // Assert
      53 |       expect(console.log).toHaveBeenCalledTimes(1);
    > 54 |       expect(console.log).toHaveBeenCalledWith('User has NOT access');
         |                           ^
      55 |     });
      56 |   });
      57 | });

      at it (src/app/sample.component.spec.ts:54:27)

I tried to call TestBed.createComponent() after store.reset() and to call detectChanges() on the component fixture, without success.

Is it a bug or I am missing something?

Environment

Libs:
- @angular/core version: 11.2.14
- @ngxs/store version: 3.7.3
@vanmxpx
Copy link
Contributor

vanmxpx commented Dec 17, 2022

Faces the same problem.
Found that this change on line breaks behavior with TestBed modules.
Pull request #105
It caches first injected Store when TestBed creates new Store in every test cycle. So you get the values from the past store.

@VerzCar
Copy link

VerzCar commented Feb 7, 2023

Can someone please approve the open PR or otherwise show some workaround?

@rbeier
Copy link

rbeier commented Dec 18, 2023

+1

1 similar comment
@faskan
Copy link

faskan commented Jan 8, 2024

+1

@stockmind
Copy link

Stumbled upon this issue myself yesterday. Had to rely on jest.spyOn to override the selector.
Can #154 be reviewed and merged as it apparently fix the issue? @arturovt
@vanmxpx i see #152 is still open, can it be closed to avoid confusion?

@markwhitfeld
Copy link
Member

I have merged PR #154. @arturovt could you do a release for this?

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

7 participants