2014-10-06 21 views
8

Tôi đã phát triển các thành phần Om/React, nhưng tôi cảm thấy thực sự không thoải mái khi không thể thúc đẩy sự phát triển của tôi với các bài kiểm tra đơn vị. Tôi đã cố gắng để thiết lập dự án clojurescript của tôi để chạy thử nghiệm đơn vị trên các thành phần đó, và cho đến nay đạt đến điểm mà tôi có thể viết các bài kiểm tra đơn vị và khởi tạo các thành phần của tôi. Những gì tôi thiếu là khả năng đảm bảo các thành phần của tôi phản ứng đúng với một số sự kiện, ví dụ: onChange để tôi có thể mô phỏng đầu vào của người dùng.Làm thế nào để kiểm tra thành phần Om/React đúng cách (đơn vị)?

Đây là mã thử nghiệm của tôi:

(defn simulate-click-event 
    "From https://github.com/levand/domina/blob/master/test/cljs/domina/test.cljs" 
    [el] 
    (let [document (.-document js/window)] 
    (cond 
    (.-click el) (.click el) 
    (.-createEvent document) (let [e (.createEvent document "MouseEvents")] 
           (.initMouseEvent e "click" true true 
               js/window 0 0 0 0 0 
               false false false false 0 nil) 
           (.dispatchEvent el e)) 
    :default (throw "Unable to simulate click event")))) 

(defn simulate-change-event 
    "From https://github.com/levand/domina/blob/master/test/cljs/domina/test.cljs" 
    [el] 
    (let [document (.-document js/window)] 
    (cond 
    (.-onChange el) (do (print "firing on change on " el) (.onChange el)) 
    (.-createEvent document) (let [e (.createEvent document "HTMLEvents")] 
           (print "firing " e " on change on " (.-id el)) 
           (.initEvent e "change" true true) 
           (.dispatchEvent el e)) 
    :default (throw "Unable to simulate change event")))) 

(def sink 
    "contains a channel that receives messages along with notification type" 
    (chan)) 

;; see http://yobriefca.se/blog/2014/06/04/publish-and-subscribe-with-core-dot-asyncs-pub-and-sub/ 
(def source 
    (pub sink #(:topic %))) 

(defn change-field! 
    [id value] 
    (let [el (sel1 (keyword (str "#" id)))] 
    (dommy/set-value! el value) 
    (simulate-change-event el) 
    )) 

(deftest ^:async password-confirmation 
    (testing "do not submit if passwords are not equal" 
    (let [subscription (chan)] 
     (sub source :user-registration subscription) 
     (om/root 
     (partial u/registration-view source sink) 
     nil 
     {:target (sel1 :#view)}) 

     (go 
     (let [m (<! subscription)] 
     (is (= :error (:state m))) 
     (done) 
     )) 

     (change-field! "userRequestedEmail" "[email protected]") 
     (change-field! "userRequestedPassword" "secret") 
     (change-field! "confirmPassword"  "nosecret") 

     (simulate-click-event (sel1 :#submitRegistration)) 
    ))) 

thử nghiệm này chạy nhưng không thành công vì change-field! chức năng không thực sự thay đổi trạng thái của các thành phần. Dưới đây là (một phần của) mã của thành phần (tha thứ cho sự trùng lặp ...):

(defn registration-view 
    "Registration form for users. 

    Submitting form triggers a request to server" 
    [source sink _ owner] 
    (reify 

    om/IInitState 
    (init-state [_] 
       {:userRequestedEmail "" 
       :userRequestedPassword "" 
       :confirmPassword ""} 
       ) 

    om/IRenderState 
    (render-state 
    [this state] 
    (dom/fieldset 
     nil 
     (dom/legend nil "User Registration") 
     (dom/div #js { :className "pure-control-group" } 

       (dom/label #js { :for "userRequestedEmail" } "EMail") 
       (dom/input #js { :id "userRequestedEmail" :type "text" :placeholder "Enter an e-mail" 
           :value (:userRequestedEmail state) 
           :onChange #(om/set-state! owner :userRequestedEmail (.. % -target -value))})) 

     (dom/div #js { :className "pure-control-group" } 
       (dom/label #js { :for "userRequestedPassword" } "Password") 
       (dom/input #js { :id "userRequestedPassword" :type "password" :placeholder "Enter password" 
           :value (:userRequestedPassword state) 
           :onChange #(om/set-state! owner :userRequestedPassword (.. % -target -value))})) 

     (dom/div #js { :className "pure-control-group" } 
       (dom/label #js { :for "confirmPassword" } "") 
       (dom/input #js { :id "confirmPassword" :type "password" :placeholder "Confirm password" 
           :value (:confirmPassword state) 
           :onChange #(om/set-state! owner :confirmPassword (.. % -target -value))})) 


     (dom/button #js {:type "submit" 
         :id "submitRegistration" 
         :className "pure-button pure-button-primary" 
         :onClick #(submit-registration state sink)} 
        "Register"))))) 

Những gì tôi có thể nhìn thấy bằng cách đặt dấu vết trong các bài kiểm tra là tình trạng của các thành phần không được cập nhật khi tôi kích hoạt change sự kiện, mặc dù nó được kích hoạt chính xác. Tôi nghi ngờ điều này đã làm với cách Om/React hoạt động, bao gồm các thành phần DOM, nhưng không chắc chắn làm thế nào để đối phó với điều này.

+0

Chỉ cần đảm bảo: là thành phần thử nghiệm của bạn được đưa ra bởi om ở tất cả (thậm chí chỉ trong bộ nhớ '?), Bạn có thể xác nhận DOM các phần tử thực sự được tạo và trình xử lý onChange được đính kèm? – phtrivier

+0

Có. Sự kiện 'on click' được kích hoạt, tôi có thể thấy thông báo đi qua kênh core.async: Đó là những gì' submit-registration' thực hiện, gửi kết quả của cuộc gọi xhrio tới kênh 'source' mà sau đó nhận được '(go ...)' vòng lặp bên trong thử nghiệm. – insitu

+0

@insitu Có lẽ cách tiếp cận khác nhau sẽ giúp ích. Tôi thử nghiệm các thành phần phản ứng bằng cách sử dụng mochify và tôi đã thêm một ví dụ vào trang wiki của mochify: https://github.com/mantoni/mochify.js/wiki/Testing-a-ReactJS-Component-with-Mochify –

Trả lời

1

Bạn có thể thử các sự kiện trong các thành phần của mình bằng ReactTestUtils từ thư viện phản ứng. Tôi đang sử dụng mocha và làm một cái gì đó như thế này để kiểm tra các sự kiện thay đổi:

var comp = ReactTestUtils.renderIntoDocument(<Component />); 
var changingElement = ReactTestUtils.findRenderedDOMComponentWithClass(comp, 'el-class'); 
it ('calls myChangeMethod on change', function() { 
    ReactTestUtils.Simulate.change(changingElement); 
    assert(comp.myChangeEventMethod.called, true); 
} 
Các vấn đề liên quan