【问题标题】:unit test stateless component method单元测试无状态组件方法
【发布时间】:2017-11-30 16:20:09
【问题描述】:

我有 react 的这个无状态组件

const Clock = () => {
    const formatSeconds = (totalSeconds) => {
        const seconds = totalSeconds % 60,
        minutes = Math.floor(totalSeconds / 60)

        return `${minutes}:${seconds}`
    }
    return(
        <div></div>
    )
}

export default Clock

如何测试 formatSeconds 方法?

我写了这个,测试失败了。

import React from 'react'
import ReactDOM from 'react-dom'
import expect from 'expect'
import TestUtils from 'react-addons-test-utils'

import Clock from '../components/Clock'

describe('Clock', () => {
    it('should exist', () => {
        expect(Clock).toExist()
    })

    describe('formatSeconds', () => {
        it('should format seconds', () => {
            const Clock = TestUtils.renderIntoDocument(<Clock />)
            const seconds = 615
            const expected = '10:15'
            const actual = Clock.formatSeconds(seconds)

            expect(actual).toBe(expected)
        })
    })
})

第一个测试通过了,但可能在执行 Clock.formatSeconds 时出现问题。

【问题讨论】:

  • 我不明白你的组件。为什么你的函数里面有一个永远不会被使用或暴露的函数?

标签: javascript unit-testing reactjs ecmascript-6 karma-runner


【解决方案1】:

组件Clock是一个函数,在组件渲染时调用。 formatSeconds 方法是在 Clock 闭包内定义的,它不是 Clock 的属性,所以你无法从外部访问它。

此外,您在每次渲染时都在重新创建formatSeconds 方法,并且由于该方法实际上并未使用范围内的任何道具,因此有点浪费。因此,您可以取出该方法,然后将其导出。您也可以将其移至另一个实用程序文件并导入,因为它不是 Clock 的组成部分,您可能希望在其他地方重用它。

export const formatSeconds = (totalSeconds) => {
    const seconds = totalSeconds % 60,
    minutes = Math.floor(totalSeconds / 60)

    return `${minutes}:${seconds}`
}

const Clock = () => {
    return(
        <div></div>
    )
}

export default Clock

现在测试也很容易:

import React from 'react'
import ReactDOM from 'react-dom'
import expect from 'expect'
import TestUtils from 'react-addons-test-utils'

import Clock, { formatSeconds } from '../components/Clock' // import formatSeconds as well

describe('Clock', () => {
    it('should exist', () => {
        expect(Clock).toExist()
    })

    describe('formatSeconds', () => {
        it('should format seconds', () => {
            const seconds = 615
            const expected = '10:15'
            const actual = formatSeconds(seconds) // use it by itself

            expect(actual).toBe(expected)
        })
    })
})

【讨论】:

  • 试过你的代码,不行,还是一样的错误。
  • 1.您可以在 Clock 的主体中调用它,就像调用任何其他方法一样 - formatSeconds(totalSeconds)
  • 2.看到您已导入它 - 第一条评论,并使用它 - 第二条评论。
  • @OriDrori 这在没有酶的情况下不起作用。你得到“语法错误:意外的令牌
【解决方案2】:

聚会有点晚了,但我有两种方法想与您分享。开箱即用,您无法测试私有方法。不管它是一个无状态的组件,还是一个带有一些私有内部的简单函数。我有一个使用以下方法:

  1. 将无状态组件转换为具有公共方法的类。是的,这超出了目的。但这仍然是一种选择。

  2. 保留无状态组件并将私有方法声明为“静态”。

const Button = onClick => {
   return <button onClick={Button.handleClick}> My Button </button>;
}

Button.handleClick = e => e.stopPropagation();

ReactDOM.render(<Button />, document.getElementById('root'));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

【讨论】:

    猜你喜欢
    • 2019-05-20
    • 2020-09-09
    • 2019-07-20
    • 2018-06-21
    • 2019-05-11
    • 1970-01-01
    • 2020-04-02
    • 2010-09-19
    相关资源
    最近更新 更多