Disable CSSTransitionGroup reaction in test

I use CSSTransitionGroup to animate an element when it appears in the DOM, or when it exits the DOM. It works well.

Now - I want to unit test this component. I create a temporary DOM node, and I attach it to <body> , I transfer my component to it, and then I perform some actions. As a result, I expect the DOM node child to disappear.

Problem: Animation classes are applied, and the component is stored in the DOM until the end of the CSS animation. This means that my test must also wait a few hundred milliseconds before I can claim that this element has disappeared. I cannot do this - I want my tests to be fast, since these are unit tests.

Question: Is there a way to disable CSS transitions without adding additional parameters for my component?

What I tried: Module testing itself works well. I can get rid of the animation by passing a parameter to my component, which will cause it not to use CSSTransitionGroup . So the worst case scenario - I will do just that. But I'm looking for a better solution.

I could also claim that the classes -enter "/" - enter-active "/" - leave "/" - leave-active "are present in the corresponding element. This seems a bit hacked, although, as I could imagine, an error where these classes will be applied, but the element will remain in the DOM. I would prefer not to resort to this approach.

+7
unit-testing reactjs reactcsstransitiongroup
source share
4 answers

I believe there is a proxyquire solution using proxyquire ( proxyquireify in my browserify build). Inspired by previous answers.

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

Hope this helps future readers of this issue.

+1
source share

I went with an approach that, on the one hand, makes it easier to turn off the animation in the test, and on the other hand, it does not require any specific test parameters that will be supported by each of the animated components.

Since I use ClojureScript, the syntax may not be familiar to some, but I will comment on it a bit to make it clearer:

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

In regular code, this class will be used in exactly the same way as the standard CSSTransitionGroup .

However, in unit tests, I can bind animations-enabled as false and safely state that DOM elements are added / removed immediately:

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

I had a very difficult time discussing the answer provided by ClojureScript, which had a similar requirement, and noted that this was apparently the only google return result.

Here is how I solved it using sinon:

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

Basically cut out the entire css transition group for rendering inside a div passing through child elements. It may not be very pretty, but it seems to work very well for my needs.

0
source share

In accordance with this plans

reaction-addon-css-transition-group is deprecated. So maybe instead of react-motion ?

0
source share

All Articles