使用axios对提交进行反应测试

时间:2017-08-30 14:59:57

标签: javascript reactjs unit-testing axios

我最近开始测试我的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()

感谢。

1 个答案:

答案 0 :(得分:0)

这里的关键是使您的代码“可测试”。分离责任有助于使您的代码更易于测试,易读且易于维护。在您的情况下,通过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)
    }
}

正如您所看到的,分离逻辑有助于测试。此外,它还可以帮助您避免使用包含大量代码的组件。您可以测试组件的状态和显示 希望这能回答你的问题!