2016-04-11 14 views
7

DOMに表示されるとき、またはDOMから離れるときに要素をアニメートするにはCSSTransitionGroupを使用しています。それはうまくいく。テストでReactのCSSTransitionGroupを無効にする

今、このコンポーネントをユニットテストしたいと思います。私は一時的なDOMノードを作成して、<body>に接続し、コンポーネントをレンダリングしてから、いくつかの処理を実行します。その結果、私は子供のDOMノードが消滅することを期待しています。

問題: アニメーションクラスが適用され、CSSアニメーションが終了するまでコンポーネントがDOMに保持されます。これは、私のテストが、その要素がなくなったと主張できるようになるまで、数百ミリ秒も待たなければならないことを意味します。私はそれをすることはできません - 私は私のテストが素早くなることを望みます、それらはユニットテストです。

質問: コンポーネントに余分なオプションを追加せずにCSSトランジションを無効にする方法はありますか?

私が試したもの: ユニットテスト自体はうまくいきます。 CSSTransitionGroupを使用しないようにするパラメータをコンポーネントに渡すことで、アニメーションを取り除くことができます。だから最悪のシナリオ - 私はそれだけでやります。しかし、私はより良い解決策を探しています。

"-enter"/"enter-active"/"leave"/"leave-active"クラスは、問題の要素に存在すると主張することもできます。しかし、私はこれらのクラスが適用されるバグを想像することができますが、要素はDOMに残っています。私はこのアプローチに頼らない方がいいです。

+0

コンポーネントをモックすることができます。あなたがJestを使っているなら、['ReactTestUtils.mockComponent'](https://facebook.github.io/react/docs/test-utils.html#mockcomponent)を使うことができます。私は 'CSSTransitionGroup'の機能性を直接テストすることを心配しません。 – Aaron

+0

テストを実行しているときに、反応している部品をパッチする方法はありますか?そこでCSSTransitionGroupを無効にします。 – goldylucks

+0

私は一種のことを最後に@AdamGoldmanでした。あなたはおそらくここで私自身の質問に答えなければならないことを思い出しました。 – kamituel

答えて

0

私は、一方ではテストでアニメーションを無効にすることが容易になりました。もう一方では、アニメーション化された各コンポーネントでテスト固有のパラメータをサポートする必要はありません。

私はClojureScriptを使用するので、構文は一部になじみのないかもしれないが、私はそれをより明確にするために、それを少しコメントします:

;; By default, in non-unit-test code, animations are enabled. 
(def ^:dynamic animations-enabled true) 

;; Custom component that essentially wraps React.addons.CSSTransitionGroup, 
;; but modifies props passed to it whenever animations-enabled 
;; is set to false. 
(def css-transition-group 
    (let [rc-anim-cls (rc/adapt-react-class js/React.addons.CSSTransitionGroup)] 
    (rc/create-class 
    {:reagent-render 
    (fn [anim-spec & children] 
     (let [anim-spec-2 (if animations-enabled 
          ;; If animations are enabled, 
          ;; pass props through with no change. 
          anim-spec 
          ;; If animations are disabled, 
          ;; override that in props before passing 
          ;; them to CSSTransitionGroup. 
          (assoc anim-spec 
            :transition-enter false 
            :transition-leave false))] 
     (into [rc-anim-cls anim-spec-2] children)))}))) 

通常のコードでは、このクラスはまったく同じように使用されます標準としてCSSTransitionGroupが使用されます。ユニットテストで

、しかし、私はfalseとしてanimations-enabledを結合して、安全に直ちに削除/追加されたDOM要素に主張することができます。

(binding [anim/animations-enabled false] 
    ;; Create component that uses animations. It will not be 
    ;; animated though. 
) 
+0

誰かがなぜ私の答えをdownvotes愛する理由は何のコメントもありません。どんなことがあっても...このアプローチは今のところ私たちのためにうまくいきます。 – kamituel

0

私が提供ClojureScriptの答えについては本当に大変な時間の推論を持っていた、持っていました同様の要件とこれは一見Googleの結果が返されたことに注目してください。

は、ここで私はsinonを使用して、それを解決した方法は次のとおりです。

transitionGroupStub = sinon.stub(ReactCSSTransitionGroup.prototype, 'render', function() { 
     return React.createElement('DIV', null, this.props.children) 
    }) 

は基本的に子供たちに沿って通過するdivの内側に描画するために全体のCSSトランジショングループをスタブアウト。これはきれいではないかもしれませんが、私のニーズにはうまくいくようです。

+0

私はLispが最初は読みにくいと聞いています;しかし、あなたの解は意味があります。それは私のものと100%同じではありません(テスト固有のクラスで 'CSSTransitionGroup'をラップするとスタブを使用します)、私は私のほうが少しきれいだと言いたいです。乾杯! – kamituel

1

proxyquirebrowserifyベースのビルドにはproxyquireify)を使用して解決策があると思います。以前の答えに触発されました。

./stubs/react_css_transition_group.js

const { createElement: el, Component } = require('react') 

class ReactCSSTransitionGroup extends Component { 
    constructor(props) { 
    super(props) 
    } 

    render() { 
    const { children, component } = this.props 

    return el(component, null, children) 
    } 
} 

ReactCSSTransitionGroup.defaultProps = { 
    component: 'div' 
} 

module.exports = ReactCSSTransitionGroup 

./foo_test.js:この質問の未来の読者を助け

const test = require('tape') 
const { mount } = require('enzyme') 
const { createElement: el } = require('react') 
const proxyquire = require('proxyquireify')(require) 

const CSSTransitionGroup = require('./stubs/react_css_transition_group') 

const Foo = proxyquire('../src/foo', { 
    'react-addons-css-transition-group': CSSTransitionGroup 
}) 

/* pseudocode */ 
test('something about bar', (assert) => { 
    assert.plan(1) 

    const foo = el(Foo) 
    const wrapper = mount(foo) 

    assert.equal(wrapper.find('p').first().text(), 'bar') 
}) 

希望。

0

このplans

によれば、非推奨の下で、アドオン-CSS-遷移基が反応します。代わりにreact-motionを代わりに使用しますか?