React testing onSubmit using axios

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-07 02:59:27

Key here is to make your code "testable". Separating responsibility helps to make your code more testable, readable and easy to maintain. In your case logic to post data over an API lies in some service which will handle api requests for your app, and you can test it separately.
Coming back to your question, I am providing you one of the possible solutions for testing async calls in your case:

// 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
    })
);

Again you can test above code separately.

// 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();
});

In above tests you can use different mocking methods or libraries.
And finally your component will look something like this

// 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)
    }
}

As you can see separating out logic helps in testing. Further it will save you from ending up with component with tons of code in it. You can test your component for its state and presentation.
Hope this answers your question!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!