【问题标题】:React testing onSubmit using axios使用 axios 对 onSubmit 进行反应测试
【发布时间】:2018-02-08 08:48:11
【问题描述】:

我最近开始测试我的 React 应用程序。但是,我在处理提交表单时绊倒了。我的测试涵盖了大部分行,但错过了提交表单方法的实际部分

LoginForm.js - 提交表单

          const userLoginData = {
              userId : this.state.userId,
              password : this.state.password,
              userType : this.state.userType
          };

          axios({
              data : JSON.stringify(userLoginData),
              type : 'post',
              url : Constant.BASE_URL_SERVER+'/rest/login',
              headers : {
                  'Accept': 'application/json',
                  'Content-Type': 'application/json'
              },
              cache : false
           })
           .then(function (response) {
              //alert("Form Submitted.");
              this.setState({isLoggedIn : true});
              this.setState({loginResponse : "Login Success!"});
              if(this.state.userType === 'Customer'){
    ...

login_form-test.js

        describe('testing form submission onSubmit', () => {
            const testData = {
                userId: '00000000',
                password: 'SamplePassword0',
                userType: 'Customer',
                validForm: true,
            }

            it('should submit form onSubmit()', () => {
                const mountedComponentHandle = mount(<LoginForm {...testData}/>);
                const onSubmitForm = sinon.spy(
                    mountedComponentHandle.instance(),
                    'handleSubmitForm'
                );
                mountedComponentHandle.update();
                const formHandle = mountedComponentHandle.find('form');
                expect(formHandle.length).toBe(1);

                formHandle.simulate('submit');
                expect(onSubmitForm.called).toBe(true);
            });
        });

请建议如何测试 axios 的 .then().catch()

谢谢。

【问题讨论】:

    标签: javascript reactjs unit-testing axios


    【解决方案1】:

    这里的关键是让您的代码“可测试”。职责分离有助于使您的代码更具可测试性、可读性和易于维护性。在您的案例中,通过 API 发布数据的逻辑在于某些服务,该服务将为您的应用处理 api 请求,您可以单独对其进行测试。
    回到您的问题,我为您提供了一种可能的解决方案,用于在您的情况下测试异步调用:

    // apiGateway.js
    const postData = (url, data) => (
        axios({
            data: JSON.stringify(data),
            type: 'post',
            url: BASE_URL_SERVER + url,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            cache: false
        })
    );
    

    同样你可以单独测试上面的代码。

    // myAppApi.js
    const postLoginForm = (data, callback, errorCallback) => {
        return postData('/rest/login', data)
            .then((response) => callback(response.data))
            .catch((error) => errorCallback(error))
    
    };
    
    // myAppApi.test.js
    // import * as myAppApi from '../myAppApi'
    it('should call callback when response is successful', async () => {
        const mockResponse = {};
        const mockRequestData = {};
        const mockSuccessCallback = jest.fn();
        const mockErrorCallback = jest.fn();
    
        spyOn(myAppApi, 'postLoginForm').and.returnValue(Promise.resolve(mockResponse));
    
        await myAppApi.postLoginForm(mockRequestData, mockSuccessCallback, mockErrorCallback);
    
        expect(mockSuccessCallback).toHaveBeenCalled();
    });
    
    it('should call error callback when response is failed', async () => {
        const mockRequestData = {};
        const mockSuccessCallback = jest.fn();
        const mockErrorCallback = jest.fn();
    
        spyOn(myAppApi, 'postLoginForm').and.returnValue(Promise.reject());
    
        await myAppApi.postLoginForm(mockRequestData, mockSuccessCallback, mockErrorCallback);
    
        expect(mockErrorCallback).toHaveBeenCalled();
    });
    

    在上述测试中,您可以使用不同的模拟方法或库。
    最后你的组件看起来像这样

    // LoginForm.js
    class LoginForm extends React.Component {
        onSuccessfulLogin(responseData) {
            //.. success logic here
        }
    
        onFailedLogin(error) {
            //.. error logic here
        }
    
        onSubmitForm(event) {
            postLoginForm(this.state.data, this.onSuccessfulLogin, this.onFailedLogin)
        }
    }
    

    如您所见,分离逻辑有助于测试。此外,它将使您免于最终使用包含大量代码的组件。您可以测试组件的状态和表示。
    希望这能回答您的问题!

    【讨论】:

      猜你喜欢
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 2020-01-19
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 2022-11-26
      相关资源
      最近更新 更多