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

如何在Ember集成测试中配置ember-intl服务?

解决Ember集成测试中ember-intl "No locale defined" 报错问题

你的问题我太熟悉了——旧版ember-intl文档的测试示例确实跟不上Ember的迭代节奏,尤其是moduleForComponent和container.lookup这些API早就被淘汰了。核心原因是集成测试环境里,ember-intl服务没被正确初始化:既没设置locale,也没加载翻译文件,导致组件调用翻译时直接报错。

下面给你两种实用的解决方案,根据你的测试需求选就行:

方案一:初始化真实的ember-intl服务(适合需要验证真实翻译的测试)

用新版Ember测试API,在beforeEach钩子中通过this.owner获取intl服务,手动设置locale并加载翻译:

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | x-product', function(hooks) {
  setupRenderingTest(hooks);

  hooks.beforeEach(function() {
    // 获取intl服务(替代旧的container.lookup)
    const intlService = this.owner.lookup('service:intl');
    // 设置测试用的locale
    intlService.setLocale('en-us');
    
    // 如果你的翻译是按文件组织的,手动加载对应翻译(按需添加)
    // 比如你的en-us翻译在app/translations/en-us.js里:
    // intlService.addTranslations('en-us', require('my-app/translations/en-us').default);
  });

  test('it renders with correct translations', async function(assert) {
    await render(hbs`{{x-product price=price deadline=deadline}}`);
    
    this.set('price', 1000);
    this.set('deadline', new Date());

    // 替换成你实际要验证的翻译文本
    assert.dom().containsText('Your translated price label here');
  });
});

如果你的应用是通过ember-intl的构建流程自动注入翻译的,可能不需要手动调用addTranslations,但测试环境偶尔会有加载延迟,这时可以加个waitFor确保翻译加载完成。

方案二:存根intl服务(适合只验证组件逻辑的测试)

如果你的测试不需要关心真实翻译内容,只是想确保组件正确调用了翻译方法,直接存根intl的t方法更简单:

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { stubService } from 'ember-qunit';

module('Integration | Component | x-product', function(hooks) {
  setupRenderingTest(hooks);

  hooks.beforeEach(function() {
    // 存根intl服务的t方法,直接返回key或者自定义文本
    stubService('intl', {
      t(key) {
        // 可以返回带标记的key,方便测试断言
        return `[TRANSLATED: ${key}]`;
        // 也可以针对特定key返回固定文本:
        // if (key === 'product.price') return 'Price:';
        // return key;
      }
    });
  });

  test('it uses translation service', async function(assert) {
    await render(hbs`{{x-product}}`);
    
    // 验证存根的输出
    assert.dom().containsText('[TRANSLATED: product.price]');
  });
});

关键提醒

  • 新版Ember测试中,this.owner是获取容器内服务/对象的标准方式,替代了旧的this.container。
  • 如果用的是组件级翻译(比如每个组件单独的translation文件),要么确保测试能加载到这些文件,要么用存根跳过真实翻译的依赖。
  • 异步翻译加载的场景:如果你的翻译是异步加载的,记得用await waitFor(...)等待翻译就绪后再做断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:56:04