2017-08-30 81 views
1

我最近开始测试我的React应用程序。然而,我在处理提交表单时偶然发现。我的测试覆盖了大部分行,但错过了实际部分的提交表单方法反应测试onSubmit使用axios

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

如何测试请建议0和.catch() axios。

谢谢。

回答

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

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