2016-04-11 19 views
7

Sto usando CSSTransitionGroup per animare un elemento quando appare nel DOM o quando lascia il DOM. Funziona bene.Disabilita React's CSSTransitionGroup in prova

Ora - Voglio testare questo componente. Sto creando un nodo DOM temporaneo e lo allego allo <body>, eseguo il rendering del mio componente e quindi eseguo alcune azioni. Di conseguenza, mi aspetto che un nodo DOM figlio scompaia.

Il problema: Le classi di animazione vengono applicate e il componente viene mantenuto nel DOM fino alla fine delle animazioni CSS. Questo significa che il mio test dovrebbe aspettare anche qualche centinaio di millisecondi prima che possa affermare che quell'elemento è andato via. Non posso farlo, voglio che i miei test siano veloci, poiché si tratta di test unitari.

La domanda: C'è un modo per disabilitare le transizioni CSS senza aggiungere opzioni extra al mio componente?

Quello che ho provato: Test di unità funziona bene. Posso liberarmi delle animazioni passando un parametro al mio componente che non lo farà usare CSSTransitionGroup. Quindi, nel peggiore dei casi, farò proprio questo. Ma sto cercando una soluzione migliore.

Potrei anche affermare che le classi "-enter"/"- enter-active"/"- leave"/"- leave-active" sono presenti su un elemento in questione. Tuttavia, sembra un po 'hacky, dato che potrei immaginare un bug in cui verrebbero applicate tali classi, ma l'elemento rimarrebbe nel DOM. Preferirei non ricorrere a questo approccio.

+0

È possibile prendere in giro il componente. Se stai usando Jest puoi usare ['ReactTestUtils.mockComponent'] (https://facebook.github.io/react/docs/test-utils.html#mockcomponent). Non mi preoccuperei di testare direttamente la funzionalità di 'CSSTransitionGroup'. – Aaron

+0

in che modo la patch moneky reagisce durante l'esecuzione dei test? e quindi disabiliti CSSTransitionGroup lì. – goldylucks

+0

L'ho fatto alla fine, @AdamGoldman. Mi hai ricordato che probabilmente dovrei rispondere alla mia domanda qui. – kamituel

risposta

0

Sono andato con l'approccio che, da un lato, rende facile disabilitare le animazioni nel test, e dall'altro - non richiede alcun parametro specifico di test per essere supportato da ciascuno dei componenti animati.

Da quando uso ClojureScript, la sintassi potrebbe essere poco familiare per alcuni, ma io commento un po 'per renderlo più chiaro:

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

Nel codice di regolare, questa classe verrà utilizzato esattamente nello stesso modo come standard si utilizzerà CSSTransitionGroup.

Nel test di unità, tuttavia, posso legare animations-enabled come false e far valere in modo sicuro su elementi DOM per essere aggiunti/rimossi immediatamente:

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

Amo quando qualcuno downvotes la mia risposta senza commento sul perché. Qualunque ... questo approccio funziona bene per noi finora. – kamituel

0

ho avuto un momento ragionare davvero difficile per la risposta ClojureScript fornito, avuto un simile requisito e notato questo è apparentemente l'unico risultato di google restituito.

Ecco come ho risolto, usando Sinon:

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

Fondamentalmente spegnere l'intero gruppo CSS transizione per rendere all'interno di un passaggio div lungo i bambini. Questo potrebbe non essere carino, ma sembra funzionare abbastanza bene per i miei bisogni.

+0

Ti sento, Lisp è difficile da leggere all'inizio;) Tuttavia, la tua soluzione ha senso. Non è uguale al 100% del mio (comprendo 'CSSTransitionGroup' in una classe specifica per il test, usi stub), quindi direi che il mio è un po 'più pulito - forse, ma il tuo evita una classe extra. Saluti! – kamituel

1

Credo che ci sia una soluzione più pulita utilizzando proxyquire (proxyquireify nella mia build basata su browserify). Ispirato alle risposte precedenti.

./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') 
}) 

Speranza che aiuta i futuri lettori di questo argomento.