6

I do have the following beforeEach:

beforeEach(() => {
    fixture = TestBed.createComponent(ApplyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    store = TestBed.get<Store<fromAnnouncement.AnnouncementState>>(Store);
    store.refreshState();
    mockApplicationSelector = store.overrideSelector(selectDraftApplication, testDraftApplication); <-- Try to mock  a selector here.
  });

The selector selectDraftApplication depends on the feature selector for the AnnouncementState, which has two entities in it, one of which im subselecting with a feature selector in order to build my selectDraftApplication selector.

When using this code in test, all my tests crash, because NgRx somehow still seems to look for all the state further up, when I would expect a mock to be something that prevents precisely this. There is no point in mocking out a whole ngrx entity store, so I would just like the selector to return exactly that object and be done with it. I googled wide and far, but did not get any answer. Any help? I run Angular 8 and ngrx 8.5.1 (the refreshState() function did not work either...)

Thanks!

EDIT:

export const getAnnouncementState = createFeatureSelector<AnnouncementState>('announcement');

export const getApplicationsState = createSelector(
  getAnnouncementState,
  (state: AnnouncementState) => state.applications 
);

export const selectDraftApplication = createSelector(
  getApplicationsState,
  (state: ApplicationState) => state.draftApplication
);
thomi
  • 1,603
  • 1
  • 24
  • 31
  • How does the selector look like? – timdeschryver Nov 13 '19 at 16:42
  • Hi @timdeschryver. I added the selector chain. The tests break at the second one, where applications is selected (which does not exist, as I would have to mock out an ngrx entity for doing that). All I am interested in is selecting a draftApplication – thomi Nov 13 '19 at 17:01
  • That should work imho, if you have a reproduction I'm happy to take a look – timdeschryver Nov 13 '19 at 17:38
  • 1
    There was the same question here: https://stackoverflow.com/questions/58787505/how-do-i-mock-selectors-in-nrgx-8-unit-tests/58787732#58787732. (quick answer, I don't think that mocking the selector is the best idea, but here is alternative) – Wandrille Nov 13 '19 at 19:12
  • Thanks @Wandrille. I am halfway down this path, where I set the selector directly in the MockStore, and do an override when I need it. I read several times now that mocking a selector is not the best idea. Why is that? For this Unit test, I am only interested in returning a proper value, which is checked for type by TypeScript so I can unit test my component. I wouldn't mock it if I'd test the selector itself, but what's wrong about it in this case? – thomi Nov 14 '19 at 05:08
  • Selector are nothing more than constant for mapping (`export const mySelector = createSelector(mySate, (state) => state.foo);`). And you don't mock constant, don't you. In unit test, you are tying to mock the result of particular methods. With NGRX, the easiest way to expect content from methods is to populate the store (that is nothing more than an object for the test). **BUT** Another alternative, can be to have your store inside a service and then, you can mock your service inside your component. – Wandrille Nov 14 '19 at 05:48
  • 3
    Please, stop writing, that overriding selector is not a good idea. It's just like setting an input for the test. The purest unit test. If you don't need testing the state integration this the best approach! – John Smith Dec 29 '20 at 12:45

1 Answers1

3

You need to call refreshState() after mocking the selector...

beforeEach(() => {
    fixture = TestBed.createComponent(ApplyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    store = TestBed.get<Store<fromAnnouncement.AnnouncementState>>(Store);
    //
    mockApplicationSelector = store.overrideSelector(selectDraftApplication, testDraftApplication); <-- Try to mock  a selector here.

    store.refreshState(); <-- refresh state ***after*** mocking the selector
  });
GKA
  • 1,230
  • 1
  • 15
  • 15