enzymejs / enzyme

JavaScript Testing utilities for React
https://enzymejs.github.io/enzyme/
MIT License
19.95k stars 2.01k forks source link

How can I test async method of ListPage component/wrapper while I am not getting updated wrapper #2343

Open guruusingh2033 opened 4 years ago

guruusingh2033 commented 4 years ago

How can I run and test component methods Here is the wrapper

const wrapper = mount(
<Provider store={configureStore()}>
        <IntlProvider
          locale={currentAppLocale.locale}
          messages={currentAppLocale.messages}
        >
          <MemoryRouter initialEntries={["/list"]}>
            <ListPage match={{ url: "localhost:3000", path: "list" }} location={{ state: undefined }} />
          </MemoryRouter>
        </IntlProvider>
      </Provider>
)

I want to run method and cover all statement of method for testing like wrapper.methodname() something like this

ljharb commented 4 years ago

First, pass the providers and memory router in using the wrappingComponent option, so you're wrapping ListPage directly.

What component methods did you have in mind?

guruusingh2033 commented 4 years ago

Inside list.js

  onSearchKey = e => {
    if (e.key === "Enter") {
      this.setState(
        {
          search: e.target.value.toLowerCase()
        },
        () => this.dataListRender()
      );
    }
  };
ljharb commented 4 years ago

The first thing is, never put functions in class fields - for many reasons, but one of them is it makes them untestable.

If you make it a normal instance method, and then add onSearchKey = this.onSearchKey.bind(this); above it, then you can spy on List.prototype.onSearchKey before rendering, and make assertions on the spy.

guruusingh2033 commented 4 years ago

List.js:

constructor(props) {
    super(props);
    this.changeOrderBy = this.changeOrderBy.bind(this);
 }
  changeOrderBy(column){
    this.setState(
      {
        selectedOrderOption: this.state.orderOptions.find(
          x => x.column === column
        )
      },
      () => this.dataListRender()
    );
  };

List.test.js

jest.spyOn(ListPage.prototype, 'changeOrderBy'); // ParentComponent.prototype.myMethod is now a mock function
    const wrapper = mount(
      <Provider store={configureStore()}>
        <IntlProvider
          locale={currentAppLocale.locale}
          messages={currentAppLocale.messages}
        >
          <MemoryRouter initialEntries={["/list"]}>
            <ListPage match={{ url: "localhost:3000", path: "list" }} location={{ state: undefined }} />
          </MemoryRouter>
        </IntlProvider>
      </Provider>
    );
    wrapper.instance().changeOrderBy();
    expect(spy).toHaveBeenCalled();

output: TypeError: wrapper.instance(...).changeOrderBy is not a function