Unit testing 禁用React';s CSSTransitionGroup在测试中

Unit testing 禁用React';s CSSTransitionGroup在测试中,unit-testing,reactjs,reactcsstransitiongroup,Unit Testing,Reactjs,Reactcsstransitiongroup,我使用cstransitiongroup在元素出现在DOM中或离开DOM时为其设置动画。它工作得很好 现在-我想对这个组件进行单元测试。我正在创建一个临时DOM节点,并将其附加到,将组件渲染到其中,然后执行一些操作。因此,我希望子DOM节点消失 问题: 将应用动画类,并且组件将保留在DOM中,直到CSS动画结束。这意味着我的测试也应该等待几百毫秒,然后才能断言该元素是否消失。我不能这样做——我希望我的测试速度快,因为这些都是单元测试 问题: 有没有一种方法可以在不向我的组件添加额外选项的情况下禁

我使用
cstransitiongroup
在元素出现在DOM中或离开DOM时为其设置动画。它工作得很好

现在-我想对这个组件进行单元测试。我正在创建一个临时DOM节点,并将其附加到
,将组件渲染到其中,然后执行一些操作。因此,我希望子DOM节点消失

问题: 将应用动画类,并且组件将保留在DOM中,直到CSS动画结束。这意味着我的测试也应该等待几百毫秒,然后才能断言该元素是否消失。我不能这样做——我希望我的测试速度快,因为这些都是单元测试

问题: 有没有一种方法可以在不向我的组件添加额外选项的情况下禁用CSS转换

我的尝试: 单元测试本身运行良好。我可以通过向我的组件传递一个参数,使其不使用
cstransitiongroup
来摆脱动画。所以——最坏的情况——我就这么做。但我正在寻找更好的解决方案


我还可以断言“-enter”/“-enter active”/“-leave”/“-leave active”类存在于所讨论的元素上。但这似乎有点骇人,因为我可以想象这些类将被应用的bug,但元素将保留在DOM中。我不想求助于这种方法。

我采用的方法一方面使在测试中禁用动画变得容易,另一方面,不需要每个动画组件都支持任何特定于测试的参数

由于我使用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)))})))
在常规代码中,此类的使用方式与标准
cstransitingroup
的使用方式完全相同

但是,在单元测试中,我可以将启用的
动画绑定为
false
,并安全地断言立即添加/删除的DOM元素:

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

对于ClojureScript提供的答案,我真的很难进行推理,我也有类似的要求,并指出这似乎是谷歌返回的唯一结果

下面是我如何使用sinon解决的:

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

基本上,去掉整个css转换组,以便在传递子对象的div中进行渲染。这可能不太好,但它似乎很适合我的需要。

我相信使用
proxyquire
proxyquireify
在基于
browserify
的构建中)。受到前面答案的启发

/stubs/react\u css\u transition\u 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
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')
})
import Transition from './Transition'

export { Transition }
//more exports to come as I use other parts of react-transition-group
import React from 'react'

export default (props) => (
  <div>
    {props.in ? props.children() : null}
  </div>
)
/foo\u test.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
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')
})
import Transition from './Transition'

export { Transition }
//more exports to come as I use other parts of react-transition-group
import React from 'react'

export default (props) => (
  <div>
    {props.in ? props.children() : null}
  </div>
)
希望这能帮助未来的读者解决这个问题。

根据这篇文章


react插件css转换组正在被弃用。所以,也许可以用它来代替?

使用Jest这就是我提出的解决方案。我模拟了
转换
组件。由于我的导入看起来像是从“react Transition group”导入{Transition}
这是我创建的:

根据我的jest配置,将使用我的
\uuuuumocks\uuuuu
文件夹中的任何内容,而不是任何导入

\uuuu mocks\uuuu/react transition group/index.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
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')
})
import Transition from './Transition'

export { Transition }
//more exports to come as I use other parts of react-transition-group
import React from 'react'

export default (props) => (
  <div>
    {props.in ? props.children() : null}
  </div>
)
\uuuu mocks\uuuu/react transition group/transition.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
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')
})
import Transition from './Transition'

export { Transition }
//more exports to come as I use other parts of react-transition-group
import React from 'react'

export default (props) => (
  <div>
    {props.in ? props.children() : null}
  </div>
)
从“React”导入React
导出默认值(道具)=>(
{props.in?props.children():null}
)
通过这种方式,可以立即呈现子对象—“
转换
”几乎被禁用

**这适用于
react过渡组的
v2.4.0


这帮助我摆脱了酶的动画

你可以模拟组件。如果你在开玩笑,你可以用。我不会直接测试
cstransitiongroup
的功能。在运行测试时,moneky patching react组件怎么样?然后你在那里禁用CSSTransitionGroup。我最后也这么做了@AdamGoldman。你提醒我应该在这里回答我自己的问题。我喜欢有人对我的答案投了反对票,却对原因置之不理。无论什么到目前为止,这种方法对我们很有效。可能是因为如果你是一名普通的JS开发人员,上述方法毫无意义。什么是“绑定”?全局变量?我听说,Lisp一开始很难读懂;)然而,您的解决方案是有意义的。它和我的不完全一样(我在一个特定于测试的类中包装
cstransitiongroup
,您使用存根),所以我想说我的有点干净-也许吧,但您的避免了额外的类。干杯