javascript - 使用 axios 响应测试 onSubmit

标签 javascript reactjs unit-testing axios

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

LoginForm.js - submit form

          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()

谢谢。

最佳答案

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

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

关于javascript - 使用 axios 响应测试 onSubmit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45963781/

相关文章:

javascript - YUI 测试和 DOM 测试

javascript - 什么是 es6 中的函数作用域变量 (var) 和 block 作用域变量?

javascript - AngularJS 最佳实践 : What's the best way to 'change templates' based on object data?

javascript - React JS setState 数组

javascript - 从javascript中的字符串中提取访问 token

mongodb - 如何用MongoDB(Motor)实现FastAPI的pytest

javascript - 为什么这段 javascript 在 Google Chrome 和 IE 上都可以工作,但在 Firefox 上却不行?

javascript - React JS 文件上传

c# - 如何使用单元测试断言 Linq 集合

angular - Jasmine Angular : How to write unit test for anonymous func given as args