Javascript 如何在React和Jest中进行单元测试

Javascript 如何在React和Jest中进行单元测试,javascript,reactjs,unit-testing,jestjs,es6-promise,Javascript,Reactjs,Unit Testing,Jestjs,Es6 Promise,我正在尝试为react组件编写一个单元测试。这是一个相当标准的组件,它调用承诺返回方法,并使用“then”和“catch”来处理解析。我的测试试图验证,当承诺被拒绝时,它调用了正确的方法。然而,尽管遵循了我认为是标准的模式,我无法让jest验证调用。我已经在这里列出了相关的文件,还提供了一个github示例,链接在问题的底部。该示例只是一个使用npx创建的新react应用程序,并添加了以下文件 下面是我的示例组件: import React from 'react'; import api fr

我正在尝试为react组件编写一个单元测试。这是一个相当标准的组件,它调用承诺返回方法,并使用“then”和“catch”来处理解析。我的测试试图验证,当承诺被拒绝时,它调用了正确的方法。然而,尽管遵循了我认为是标准的模式,我无法让jest验证调用。我已经在这里列出了相关的文件,还提供了一个github示例,链接在问题的底部。该示例只是一个使用npx创建的新react应用程序,并添加了以下文件

下面是我的示例组件:

import React from 'react';
import api from '../api/ListApi';

class ListComponent extends React.Component {

    constructor(props) {
        super(props);
        this.fetchListSuccess = this.fetchListSuccess.bind(this); 
        this.fetchListFailed = this.fetchListFailed.bind(this); 

    }

    fetchList() {
        api.getList()
        .then(this.fetchListSuccess)
        .catch(this.fetchListFailed);
    }

    fetchListSuccess(response) {
        console.log({response});
    };

    fetchListFailed(error) {
        console.log({error});
    };

    render() {
        return(<div>Some content</div>);
    };
}

export default ListComponent;
下面是测试用例:

import ListComponent from './ListComponent';
import api from '../api//ListApi';

describe('ListComponent > fetchList() > When the call to getList fails', () => {
    it('Should call fetchListFailed with the error', async () => {

        expect.hasAssertions();

        //Arrange
        const error = { message: "some error" };
        const errorResponse = () => Promise.reject(error);
        const componentInstance = new ListComponent();

        api.getList = jest.fn(() => errorResponse());
        componentInstance.fetchListFailed = jest.fn(() => { });

        //Act
        componentInstance.fetchList();

        //Assert
        try {
            await errorResponse;
        } catch (er) {
            expect(componentInstance.fetchListFailed).toHaveBeenCalledWith(error);
        }

    });
});
问题是测试没有执行catch块,因此,在本例中,expect.hasAssertions没有通过测试。有人能帮我理解catch块没有执行吗?在try块中包装wait并在catch中断言似乎是Js中的标准模式,但我对Js还相当陌生,并且会做出反应,显然我做错了什么

这是GitHub上的。非常感谢您在控制台中提供的任何帮助=

const errorResponse = () => Promise.reject();
await errorResponse;
//() => Promise.reject()
您正在等待一个函数,而不是调用该函数的结果。您想:

await errorResponse();
编辑:

除此之外,测试的其余部分也很混乱。我相信您实际上想要测试当调用组件的fetchList方法时会发生什么,我假设它失败了。因此,您需要在测试中调用它,并等待它的响应:

更新组件的fetchList方法以返回承诺。 Wait componentInstance.fetchList而不是Wait errorResponse 因为您在fetchList中捕获了错误,所以您永远不会输入catch或try…catch,所以您的最终测试应该如下所示: 测试:

组成部分:

fetchList() {
    return api.getList()
    .then(this.fetchListSuccess)
    .catch(this.fetchListFailed);
}
在您的控制台中:

const errorResponse = () => Promise.reject();
await errorResponse;
//() => Promise.reject()
您正在等待一个函数,而不是调用该函数的结果。您想:

await errorResponse();
编辑:

除此之外,测试的其余部分也很混乱。我相信您实际上想要测试当调用组件的fetchList方法时会发生什么,我假设它失败了。因此,您需要在测试中调用它,并等待它的响应:

更新组件的fetchList方法以返回承诺。 Wait componentInstance.fetchList而不是Wait errorResponse 因为您在fetchList中捕获了错误,所以您永远不会输入catch或try…catch,所以您的最终测试应该如下所示: 测试:

组成部分:

fetchList() {
    return api.getList()
    .then(this.fetchListSuccess)
    .catch(this.fetchListFailed);
}

我的两分钱,还有我自己的React原生应用程序:

在我的组件中,我有:

  const handleRedirect = React.useCallback(() => {
    client.clearStore()
      .then(navigation.push('SomeScreen'))
      .catch(e => logger.error('error', e));
  }, []);
  
我的测试是这样的,我想测试承诺是否被拒绝:

it('should throw an exception on clearStore rejected', async () => {
    const client = {
      clearStore: jest.fn()
    };

    const error = new Error('clearStore failed');

    client.clearStore.mockReturnValue(Promise.reject(error));

    expect.assertions(1);
    await expect(client.clearStore())
      .rejects.toEqual(Error('clearStore failed'));
  });

我的两分钱,还有我自己的React原生应用程序:

在我的组件中,我有:

  const handleRedirect = React.useCallback(() => {
    client.clearStore()
      .then(navigation.push('SomeScreen'))
      .catch(e => logger.error('error', e));
  }, []);
  
我的测试是这样的,我想测试承诺是否被拒绝:

it('should throw an exception on clearStore rejected', async () => {
    const client = {
      clearStore: jest.fn()
    };

    const error = new Error('clearStore failed');

    client.clearStore.mockReturnValue(Promise.reject(error));

    expect.assertions(1);
    await expect(client.clearStore())
      .rejects.toEqual(Error('clearStore failed'));
  });

嗨,亚当。我在wait errorResponse之后添加了括号,它现在在测试中执行catch块,但是断言失败,声明没有调用componentInstance.fetchListFailed?我觉得这是相关的,你有什么建议吗?嗨,亚当。我在wait errorResponse之后添加了括号,它现在在测试中执行catch块,但是断言失败,声明没有调用componentInstance.fetchListFailed?我觉得这是相关的,你有什么建议吗?