Jest testing promise in React gives TypeError: Cannot read property 'finally' of undefined

Asked
Active3 hr before
Viewed126 times

9 Answers

cannotpromisetestingreact
90%

TypeError: Cannot read property 'finally' of undefined, Advertising Reach developers & technologists worldwide , Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers

You need your mocked function to return a Promise, like the actual function does. So, try setting the mock's return value to a resolved Promise:

handleSubmit = {
   jest.fn(() => Promise.resolve())
}
88%

Working with JavaScript Promise comes with its own array of errors, and a popular one isTypeError: Cannot read property 'then' of undefined.,TypeError - Cannot read property 'then' of undefined is thrown when the caller is expecting a Promise to be returned and instead receives undefined. Let's consider the above examples.,In this guide, we will cover two code examples containing a bugs that cause this TypeError and then refactor the code to resolve the issue.

1
const getTaxAmount = (price, taxRate) => {
   2 Math.floor((price * taxRate) / 100);
   3
};
4
5 getTaxAmount(100, 12).then((taxAmount) => console.log(taxAmount));
load more v
72%

Pretag
 Pretag team - issue, fix, solve, resolve
65%

jest.mock('react-native-i18n', () => 'RNI18n');,and now I get this error...,add file react-native-i18n.js to mock folder with:

 FAIL __tests__\index.android.jsTest suite failed to run

 TypeError: Cannot read property 'languages' of undefined

 at Object.<anonymous> (node_modules/react-native-i18n/index.js:7:31)
    at Object.<anonymous> (src/tools.js:8:34)
       at Object.<anonymous> (src/App.js:5:12)
load more v
75%

If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail.,It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this.,You can also use the .resolves matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail.

Pretag
 Pretag team - issue, fix, solve, resolve
40%

Jest and Enzyme are the main framework and testing utilities used in testing components and utility files of mattermost-webapp. Please visit their respective documentation for detailed information on how to get started, best practices and updates.,Ensure that all functions of a component are tested. This can be done via events, state changes or just calling it directly.,When a function is passed to a component via props, make sure to test if it gets called for a particular event call or its state changes.

const baseProps = {
    active        onSubmit: jest.fn(),
    update    };

test('should match snapshot, not send email notifications', () => {
    const wrapper = shallow(<EmailNotificationSetting {...baseProps}/>);

    // Use "toMatchInlineSnapshot" whenever possible when the snapshot consists of several lines of code only
    // It creates an easier to read snapshot, inline with the test file.
    expect(wrapper).toMatchInlineSnapshot();

    // Save snapshot particularly when component has other render function like "renderOption"
    // It creates a small snapshot of that particular render function instead of the entire component
    expect(wrapper.instance().renderOption()).toMatchInlineSnapshot();

    // Only use "toMatchSnapshot" whenever above options are not possible.
    // Limit the use to one (1) snapshot only.
    // Save snapshot if it generates an easy to inspect and identifiable HTML or components that can easily verify future change.
    expect(wrapper).toMatchSnapshot();
});
load more v
22%

await actions.getGameList(MockContext),Shouldn’t the test be calling the action somewhere?,I want to test my action. My action has 1 AXIOS request and 1 mutation. I mocked my axios with jest.mock(“axios” …). I return a Promise. I defined a commit and the response of my axios request. But I have an error that my test doesn’t know my context.state. What should I do ? Do I mock my context in a wrong way ?

let url = ''
let body = {}

jest.mock("axios", () => ({
   post: jest.fn((_url, _body) => {
      return new Promise((resolve) => {
         url = _url
         body = _body
         resolve(true)
      })
   })
}))
describe('getGameList', () => {
   test('Success: should return the game list of the user and update gameList in the store', async () => {
      //const commit = jest.fn()
      const MockContext = jest.fn(() => {
         let context = {
            state: {
               user: {
                  id: 1
               }
            }
         }
         return context
      });
      const response = {
         data: [{
               id: 1,
               name: "game_name1"
            },
            {
               id: 2,
               name: "game_name2"
            }
         ]
      };

      axios.post.mockResolvedValue(response); //OR axios.post.mockImplementationOnce(() => Promise.resolve(response));

      await actions.getGameList(MockContext)
      expect(url).toBe("api/game_list_of_user")
      expect(body).toStrictEqual({
         "user_id": 1
      })

      expect(axios.post).toHaveBeenCalledTimes(1)
      //expect(commit).toHaveBeenCalledWith(mutations.UpdateGameList, true)
   });

   test('Error: an error occurred', () => {
      const errorMessage = 'Error';
      axios.post.mockImplementationOnce(() =>
         Promise.reject(new Error(errorMessage))
      );
   });

});
load more v
60%

This is pretty simple and effective! When our data starts to fetch, we set loading to true. When it’s done fetching, we set loading to false. Note that we use the finally method on our Promise since that will run regardless of whether the fetch succeeds or fails.,This is one of the more common errors you will run into when starting out with React:,The reason this works is that, while your data fetching is happening, React will call the map method on an empty data array. This is fine—nothing will be rendered and there will be no errors. Once the data loads from the API call, our data state will be set and our list will correctly render.

Cannot read property 'map' of undefined
load more v
48%

Cypress no longer throws the error "cannot read property split of undefined" in certain circumstances when application errors are thrown. Fixes #17378.,Cypress will no longer throw a Cannot read property 'isAttached' of undefined error during cypress run on Firefox versions >= 75. Fixes #6813.,Cypress can now predict upcoming assertions and modifies its behavior until the intended state has been reached.

Pretag
 Pretag team - issue, fix, solve, resolve

Other "cannot-promise" queries related to "Jest testing promise in React gives TypeError: Cannot read property 'finally' of undefined"