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
,您使用存根),所以我想说我的有点干净-也许吧,但您的避免了额外的类。干杯