lundi 27 juillet 2020

How to mock observable in React Component using jest

I'm trying to add some test to a Component that shows it's data from an Observable. The test mocks the observable with jest.doMock, but it doesn't seem it's doing anything once the test run.

This is the error message,

  ● Display History › should render history elements

    TypeError: Cannot read property 'textContent' of null

      37 |     });
      38 | 
    > 39 |     expect(container.querySelector('[data-testid="0"]').textContent).toEqual(
         |            ^
      40 |       'verlassen'
      41 |     );
      42 | 

      at Object.test (src/modules/RxjsApproach/tests/DisplayHistory.test.tsx:39:12)

The component to test,

import { history$ } from '../service/LanguageState';

const DisplayHistory: React.SFC<DisplayHistoryProps> = () => {
  const history = useObservable(history$) || [];
 
  return (
    <StyledDrawer variant="permanent" open>
      <HistoryTitle> Search history</HistoryTitle>
      <DrawerElementsList>
        {history
          .slice()
          .reverse()
          .map((word, i) => (
            <DrawerElement
              key={i}
              data-testid={i}
            >
              {word}
            </DrawerElement>
          ))}
      </DrawerElementsList>
    </StyledDrawer>
  );
};

The class which stores the observable

type stateType = {
    history: String[];
    languageInput: String;
    languageOuput: String;
};

export const state = {
    history: [],
    languageInput: '',
    languageOuput: ''
} as stateType;

export const selectedWord$ = new BehaviorSubject('');

export const history$ = selectedWord$.pipe(
    tap((word: string) => word ?  state.history = [...state.history, word] : null),
    mapTo(() =>  [...state.history] ),
);


export const selectWordAction = (word: string) => {
    selectedWord$.next(word);
};

And here's the test I'm trying to write,

 let container: any = null;
  beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
  });

  afterEach(() => {
    unmountComponentAtNode(container);
    container.remove();
    container = null;
  });

  test('should render history elements', async () => {
    const fakeHistory = ['verstehen', 'verlassen'];

    jest.doMock('../service/LanguageState', () => ({
      history$: from([fakeHistory])
    }))
    history$.subscribe(_ => console.log('test history', _))

    await act(async () => {
      render(<DisplayHistory />, container);
    });

    expect(container.querySelector('[data-testid="0"]').textContent).toEqual(
      'verlassen'
    );

    expect(container.querySelector('[data-testid="1"]').textContent).toEqual(
      'verstehen'
    ); 
  });

Aucun commentaire:

Enregistrer un commentaire