2017-08-30 56 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) 
    } 
} 

正如你可以看到分離出邏輯測試的幫助。此外,它可以讓你避免使用包含大量代碼的組件。您可以測試組件的狀態和表示。
希望這回答你的問題!