2017-03-08 4 views
0

JS 구성 요소에서 마이그레이션 한 React 구성 요소가 있습니다. 나는 스터 빙이 더 이상 작동하지 않는 것 같기 때문에 테스트를 마친 후 검사를하고 많은 실패가 있습니다. 여기에 내가 가진 문제는 'ajaxStub.getCall (0)'null을 반환한다는 것입니다Enzyme 얕은 렌더링을 사용하여 Sinon과 스터 빙

describe("performs a DELETE AJAX request",() => { 

    it ("for specified URLs", sinon.test(function() { 
     let wrapper = shallow(<ActiveDeleteButton text = "Click Me" />); 
     let instance = wrapper.instance(); 
     let ajaxStub = this.stub($, 'ajax'); 
     instance.forceUpdate() 
     wrapper.update() 
     instance.handleConfirmDelete(); 
     console.log(ajaxStub.getCall(0)); 
     let options = ajaxStub.getCall(0).args[0]; 
     assert.equal(options.url, objUt.deleteUri); 
     assert.equal(options.type, "DELETE"); 
    })); 
})); 

...

import DeleteButton from "./delete-button.jsx" 
import Dialogs from "../../dialogs"; 
import React from "react"; 
import UrlHelper from "../../helpers/url-helper"; 

export default class ActiveDeleteButton extends React.Component { 

    /** 
    * Creates an instance of ActiveDeleteButton. 
    * 
    * @param {object} props The react props collection. 
    * 
    * @memberOf ActiveDeleteButton 
    */ 
    constructor(props) { 
     super (props); 

     this.handleConfirmDelete = this.handleConfirmDelete.bind(this); 
    } 

    handleConfirmDelete() { 
     $.ajax({ 
      url: this.props.deleteUri, 
      type: `DELETE`, 
      contentType: `application/json; charset=utf-8`, 
      cache: false, 
      success: (xhr) => { 
       let successUri = this.props.successUri; 
       if (!successUri && xhr && xhr.uri) { successUri = xhr.uri; } 
       if (successUri) { UrlHelper.redirect(successUri); } 
      }, 
      error: (xhr, status) => { 
       this.showFailed(); 
      } 
     }); 
    } 

    /** 
    * Shows failure of deletion. 
    * 
    * @memberOf ActiveDeleteButton 
    */ 
    showFailed() { 
     Dialogs.alert(this.props.errorMessage); 
    } 

    /** 
    * Renders the component to the DOM. 
    * 
    * @returns the HTML to render. 
    * 
    * @memberOf ActiveDeleteButton 
    */ 
    render() { 
     return (
      <DeleteButton text = {this.props.text} 
          title = {this.props.title} 
          cancelText = {this.props.cancelText} 
          confirmText = {this.props.confirmText} 
          message = {this.props.message} 
          onConfirmDelete = {this.handleConfirmDelete} /> 
     ); 
    } 
} 

을 내 구성 요소의 그리고 여기 (응축) 테스트입니다. 이것은 args를 검사 할 수 있도록 Ajax 호출을 반환해야한다. (예전의 JS 컴포넌트에서는 이전에 사용했다.) 스텁은 비록 내 마음에 분명히 있어야하지만 결코 호출되지 않습니다.

여기에 뭔가가 있습니까?

답변

0

다른 해결책보다 해결 방법이 많으므로 더 나은 답변을 얻을 수 있습니다. 결국 나는 다음과 같은 해결 방법을 만들었습니다 ...

먼저 Ajax 요청을 처리하기 위해 새로운 클래스를 만들었습니다.

/** 
* An AJAX request wrapper. 
* Usage of this enables testing AJAX calls. 
* 
* @export AjaxRequest 
* @class AjaxRequest 
* @extends {AjaxRequest} 
*/ 
export default class AjaxRequest { 

    /** 
    * Creates an instance of AjaxRequest. 
    * @param {any} { url, type, contentType, cache, data, successCallback, errorCallback } 
    * 
    * @memberOf AjaxRequest 
    */ 
    constructor({ url, type, contentType, cache, data, successCallback, errorCallback }) { 
     Guard.throwIf(url, "url"); 
     let emptyFunc =() => {}; 

     this.url = url; 
     this.type = type.toUpperCase() || "GET"; 
     this.contentType = contentType || "application/json; charset=utf-8"; 
     this.dataType = "json"; 
     this.cache = cache || false; 
     this.data = data ? JSON.stringify(data) : undefined; 
     this.successCallback = successCallback || emptyFunc; 
     this.errorCallback = errorCallback || emptyFunc; 
    } 

    /** 
    * Executes the AJAX request. 
    * 
    * 
    * @memberOf AjaxRequest 
    */ 
    execute() { 
     $.ajax({ 
      url: this.url, 
      type: this.type, 
      contentType: this.contentType, 
      dataType: this.dataType, 
      cache: this.cache, 
      data: this.data, 
      success: this.successCallback, 
      error: this.errorCallback 
     }); 
    } 

    /** 
    * Gets a GET request. 
    * 
    * @static 
    * @param {string} url 
    * @param {function} successCallback 
    * @param {function} errorCallback 
    * @returns an AjaxRequest 
    * 
    * @memberOf AjaxRequest 
    */ 
    static get(url, successCallback, errorCallback) { 
     return new AjaxRequest({ 
      url: url, 
      type: 'GET', 
      successCallback: successCallback, 
      errorCallback: errorCallback 
     }); 
    } 

    /** 
    * Gets a POST request. 
    * 
    * @static 
    * @param {string} url 
    * @param {object} data 
    * @param {function} successCallback 
    * @param {function} errorCallback 
    * @returns an AjaxRequest 
    * 
    * @memberOf AjaxRequest 
    */ 
    static post(url, data, successCallback, errorCallback) { 
     return new AjaxRequest({ 
      url: url, 
      data: data, 
      type: 'POST', 
      successCallback: successCallback, 
      errorCallback: errorCallback 
     }); 
    } 

    /** 
    * Gets a PUT request. 
    * 
    * @static 
    * @param {string} url 
    * @param {object} data 
    * @param {function} successCallback 
    * @param {function} errorCallback 
    * @returns an AjaxRequest 
    * 
    * @memberOf AjaxRequest 
    */ 
    static put(url, data, successCallback, errorCallback) { 
     return new AjaxRequest({ 
      url: url, 
      data: data, 
      type: 'PUT', 
      successCallback: successCallback, 
      errorCallback: errorCallback 
     }); 
    } 

    /** 
    * Gets a DELETE request. 
    * 
    * @static 
    * @param {string} url 
    * @param {function} successCallback 
    * @param {function} errorCallback 
    * @returns an AjaxRequest 
    * 
    * @memberOf AjaxRequest 
    */ 
    static delete(url, successCallback, errorCallback) { 
     return new AjaxRequest({ 
      url: url, 
      type: 'DELETE', 
      successCallback: successCallback, 
      errorCallback: errorCallback 
     }); 
    } 
} 

(나는 여기에 다시 발명하는 바퀴가 있다고 느낍니다.) 다음과 같이 나는 다음

handleConfirmDelete() { 
    AjaxRequest.delete(this.props.deleteUri, 
     (xhr) => { 
      let successUri = this.props.successUri; 
      if (!successUri && xhr && xhr.uri) { successUri = xhr.uri; } 
      if (successUri) { UrlHelper.redirect(successUri); } 
     }, 
     (xhr, status) => { 
      this.showFailed(); 
     } 
    ).execute(); 
} 

다음과 같이 지금 테스트 할 수 있습니다 ...

describe("performs a DELETE AJAX request",() => { 
    let wrapper = null; 
    let instance = null; 
    let ajaxStub = null; 
    let urlHelperRedirectStub = null; 

    beforeEach(() => { 
     ajaxStub = sinon.stub(AjaxRequest.prototype, 'execute'); 
     urlHelperRedirectStub = sinon.stub(UrlHelper, 'redirect'); 
     wrapper = shallow(<ActiveDeleteButton text = "Click Me" />); 
     instance = wrapper.instance(); 
    }); 

    afterEach(() => { 
     ajaxStub.restore(); 
     urlHelperRedirectStub.restore(); 
    }); 

    it ("for default URLs", sinon.test(function() { 
     instance.handleConfirmDelete(); 
     sinon.assert.called(ajaxStub); 
     let requestInfo = ajaxStub.getCall(0).thisValue;   

     assert.equal(UrlHelper.current.url().split('?')[0], requestInfo.url); 
    })); 

    it ("for specified URLs", sinon.test(function() { 
     wrapper = shallow(<ActiveDeleteButton text = "Click Me" deleteUri="http://localhost/items/12" />); 
     instance = wrapper.instance(); 

     instance.handleConfirmDelete(); 
     sinon.assert.called(ajaxStub); 
     let requestInfo = ajaxStub.getCall(0).thisValue;   

     assert.equal("http://localhost/items/12", requestInfo.url); 
    })); 
})); 

내가 콜백을 얻을 수있는 스텁 호출의 thisValue 속성을 사용하여 ... 내 구성 요소에 내 메서드 호출을 업데이트 다른 입력에 따라 수동으로 테스트 해보십시오. 필요한 노력을 감안할 때 이상적인 솔루션은 아니지만 작동하고 재사용이 가능합니다.

그러나 나는 더 나은 방법이 있어야한다고 느낍니다.