0

I have a simple Angular component with translatable text content, which I want to test. Unfortunately, the text content of my component is always empty when running my Jasmine/Karma tests.

However, the translated text is displayed when running the application itself and I can even receive the translation directly from TranslateService in a separate Jasmine test.

How can I fix displaying the translated text in my HTML template for Jasmine/Karma?

My component "foo.component.ts":

@Component({selector: 'app-foo', template: `<p>{{ 'hello' | translate }}</p>`})
export class FooComponent {
}

My translation file "assets/i18n/en.json":

{
  "hello": "Hello World!"
}

My test "foo.component.spec.ts":

const createTranslateHttpLoader = (http: HttpClient) => new TranslateHttpLoader(http);

describe('FooComponent', () => {
  let component: FooComponent;
  let fixture: ComponentFixture<FooComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [FooComponent],
      imports: [
        HttpClientModule,
        TranslateModule.forRoot({
          loader: {provide: TranslateLoader, useFactory: createTranslateHttpLoader, deps: [HttpClient]},
          defaultLanguage: 'en'
        })
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(FooComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should display greeting', () => { // <= fails
    expect(fixture.nativeElement.textContent).toBe('Hello World!');
  });

  it('has greeting translation', async () => { // <= works
    const translation = await TestBed.inject(TranslateService).get('hello').toPromise();
    expect(translation).toBe('Hello World!');
  });
});

I'm using Angular 11.0.1 and ngx-translate 13.0.0.

4

1 回答 1

0

在我看来,可能没有必要针对实际的 i18n 文件进行测试。验证我们使用正确的翻译密钥(在您的情况下'hello')应该足够了。

我们可以从创建TranslateLoader这样的假开始:

class FakeTranslateLoader extends TranslateLoader {
  getTranslation(lang: string): Observable<any> {
    return of({
      "hello": "Hello World!"
    });
  }
}

然后,将其导入foo.component.spec.ts

beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [FooComponent],
      imports: [
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader, useClass: FakeTranslateLoader
          }
        })
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(FooComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should display greeting', () => {
    expect(fixture.nativeElement.textContent).toBe('Hello World!');
  });

于 2021-02-03T04:42:20.163 回答