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

Cypress测试Mock useTranslation钩子失败,求问题排查

关于React-Intl翻译组件的Cypress测试失败问题

组件代码(EmailSignUpView)

import { useTranslation as t } from '@utils/hooks';
<div className={styles.notifyContainer}>
      <div className={styles.notifyTextContainer}>
        <h2
          className={styles.signUpheading}
          data-test-id="email-signup-heading"
        >
          {t('email_stay_in_touch')}
        </h2>
      </div>
</div>

useTranslation钩子实现

import { useIntl } from 'react-intl';

const useTranslation = (
  id: string,
  values?: Record<string, string | number>
): string => {
  const { formatMessage } = useIntl();

  return formatMessage({ id }, values);
};

export default useTranslation;

Cypress测试代码

import { IntlProvider } from 'react-intl';
import EmailSignUpView from '@components/EmailSignUpView/EmailSignUpView';
import MockRouter from '../../cypress/support/utils';
import { enTransMessages } from '../../cypress/support/testData/testData';
import * as hooks from '@utils/hooks';

describe('Email Signup Section tests', () => {
  before(() => {
    // Stub the useTranslation hook
    cy.stub(hooks, 'useTranslation').callsFake(() => ({
      t: (key) => {
        const translations = {
          'email_stay_in_touch': 'The text that I want to test!', // Add other key-value pairs as needed
        };
        return translations[key] || key;
      },
    }));
  });

  it('validate default Heading', () => {
    cy.mount(
      <MockRouter>
        <IntlProvider locale="en" messages={enTransMessages}>
          <EmailSignUpView />
        </IntlProvider>
      </MockRouter>
    );
    cy.getByDataID(selectors.heading)
      .should('have.text', 'The text that I want to test!')
      .and('be.visible');
  });
});

测试日志

Type    Function    Alias(es)   # Calls
stub-1  useTranslation      -
spy-1       push    -
spy-2       replace -
spy-3       reload  -
spy-4       back    -
spy-5       forward -
stub-2      prefetch    2
spy-6       beforePopState  -
spy-7       emit    -
spy-8       off -
spy-9       on  -

错误原因分析

你对useTranslation的stub实现和实际钩子的调用逻辑完全不匹配:

  • 实际的useTranslation是接收id参数并直接返回字符串的函数,组件中{t('email_stay_in_touch')}直接调用该函数获取翻译文本。
  • 但测试里的stub返回了一个包含t方法的对象,导致组件调用t('xxx')时,实际是把这个对象当作函数执行,最终渲染结果不符合预期(通常会显示[object Object]或报错)。

修正方案

修改stub的callsFake逻辑,让它匹配实际钩子的函数签名和返回值类型:

before(() => {
  cy.stub(hooks, 'useTranslation').callsFake((id, values) => {
    const translations = {
      'email_stay_in_touch': 'The text that I want to test!',
    };
    // 若需要处理插值,可在这里结合values参数替换文本占位符
    return translations[id] || id;
  });
});

调整后stub的行为和实际钩子一致,组件能正确获取测试用的翻译文本,测试即可通过。

内容的提问来源于stack exchange,提问作者JeffChen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 13:07:25