You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Jest编写React SelectLanguage组件单元测试后两个用例失败如何解决

问题原因及修复方案

核心错误点

  • Select组件mock传参错误:你mock的Select组件触发onSelect时没有传递{value: 选项值}格式的参数,导致组件内handleSelect解构value失败,后续逻辑全部异常。
  • 事件追踪的spy对象错误:第三个用例你给传入的handlers.onSelect打了spy,却用它断言eventTracker.track的调用,完全搞混了监听对象。且你没有mockeventMetricsMap所属的helpers模块,也没有给eventTracker.track打spy。
  • events mock层级错误:你mock的events对象多套了一层dummyEvents,导致组件内取events.switchBuildingBlickLanguage为undefined,注意组件内事件名拼写是switchBuildingBlickLanguage(注意是Blick不是Block,确认下是否是组件笔误,这里以组件代码为准)。

修复后的测试代码

import expect from 'expect'
import { fireEvent, render } from '@testing-library/react'

import SelectLanguage from './select-language'

// 先mock helpers模块的eventMetricsMap
jest.mock('./helpers', () => ({
  eventMetricsMap: {
    buildingblocks: {
      from: 'building blocks'
    }
  }
}))

// 正确mock event-tracker,给track打spy
const trackSpy = jest.fn()
const mockEventName = 'switch building blocks language'
jest.mock(
    'cm/common/event-tracker',
    () => ({
        eventTracker: {
            track: trackSpy
        },
        events: {
            // 注意和组件内的事件名保持一致
            switchBuildingBlickLanguage: mockEventName
        }
    })
)

const languages = [
    {
        name: 'English',
        value: 'EN',
    },
    {
        name: 'Nederlands',
        value: 'NL'
    }
]

// 修复Select组件mock,点击时传递正确的参数格式
jest.mock(
    'cm/components/common/select',
    () => ({ items, handlers }) => {
        return (<div className="dropdown">
            <div className="dropdown__menu">
                {items.map((item) => (
                    <div 
                      key={item.value}
                      className="dropdown__item" 
                      onClick={() => handlers.onSelect({ value: item.value })}
                    >{item.name}</div>
                ))}
            </div>
        </div>)
    }
)

const containerPath = '.dropdown'
const itemPath = '.dropdown__item'

describe('SelectLanguage component', () => {
    // 每次测试前清空spy调用记录
    beforeEach(() => {
      jest.clearAllMocks()
    })

    it('renders in the document', () => {
        const { container } = render(
            <SelectLanguage languages={languages} handlers={{onSelect: jest.fn()}}/>
        )

        const $container = container.querySelector(containerPath)
        expect($container).toBeTruthy()
    })

    it('renders items', () => {
        const { container } = render(
            <SelectLanguage languages={languages} handlers={{onSelect: jest.fn()}}/>
        )

        const $dropdownItems = container.querySelectorAll(itemPath)
        expect([ ...$dropdownItems ].length).toBe(2)
    })

    it('track select open click', () => {
        const { container } = render(
            <SelectLanguage
                selectedLanguage={{
                    value: 'EN'
                }}
                languages={languages}
                handlers={{
                    onSelect: jest.fn()
                }}
            />
        )

        const $dropdownItem = container.querySelector(itemPath)
        fireEvent.click($dropdownItem)

        // 断言eventTracker.track的调用
        expect(trackSpy).toHaveBeenCalledWith(
            mockEventName,
            {
                from: 'building blocks',
                language: 'en'
            }
        )
    })

    it('handles action', () => {
        const spyFn = jest.fn()

        const { container } = render(
            <SelectLanguage
                selectedLanguage={{
                    value: 'EN'
                }}
                languages={languages}
                handlers={{
                    onSelect: spyFn
                }}
            />
        )

        const $dropdownItem = container.querySelector(itemPath)
        fireEvent.click($dropdownItem)

        expect(spyFn).toHaveBeenCalledWith('EN')
    })
})

额外注意点

  • 组件内useEffect的依赖数组为空,且没有卸载时取消监听hashHistory的逻辑,可能导致内存泄漏,建议补充unlisten的返回清除逻辑。
  • 组件内事件名switchBuildingBlickLanguage大概率是拼写错误(Blick应该是Block),建议确认修改避免线上埋点丢失。

内容的提问来源于stack exchange,提问作者karo-s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:15:00