Кипарис: как имитировать использование перевода в тесте?

Я хочу попросить, чтобы у меня был компонент EmailSignUpView, который использует react-intl для перевода текстового контента.

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;

и вот мой тест

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  -

🤔 А знаете ли вы, что...
React использует компонентную архитектуру для организации кода.


1
64
1

Ответ:

Решено

stub().callFake() должен предоставлять тот же тип результата, что и сам крючок (введите string в соответствии с реальным хуком).

Вместо этого вы возвращаете объект, возможно, пытаясь реализовать эквивалентный код для перехватчика?

Попробуйте вернуть строку, самое простое:

cy.stub(hooks, 'useTranslation').callsFake(() => {
  return 'The text that I want to test!';
})

...

cy.getByDataID(selectors.heading)
  .should('have.text', 'The text that I want to test!')

Если вы хотите использовать несколько переводов, используя параметр реального хука, возможно, это — предполагая, что id — это языковой ключ:

cy.stub(hooks, 'useTranslation').callsFake((id, values) => {
  const translations = {
    'en': 'The text that I want to test!', 
    'zh': '我想要测试的文本', 
    'es': 'El texto que quiero probar.', 
    'ar': 'النص الذي أريد اختباره'
  };
  return translations[id] || 'not found'
})