1. ホーム
  2. angular

子コンポーネントのモック化 - Angular 2

2023-08-04 22:18:04

質問

テスト時に子コンポーネントをモックする方法は?親コンポーネントである product-selected という親コンポーネントがあり、そのテンプレートは以下のようなものです。

<section id="selected-container" class="container-fluid">
    <hr/>
  <product-settings></product-settings>
  <product-editor></product-editor>
  <product-options></product-options>
</section>

そして、コンポーネント宣言は次のようになります。

import { Component, Input }               from '@angular/core'; 

import { ProductSettingsComponent } from '../settings/product-settings.component';                                      
import { ProductEditorComponent }   from '../editor/product-editor.component';                                      
import { ProductOptionsComponent }  from '../options/product-options.component';                                        

@Component({
    selector: 'product-selected',
    templateUrl: './product-selected.component.html',
    styleUrls: ['./product-selected.component.scss']
})
export class ProductSelectedComponent {}

このコンポーネントは、実際には他のコンポーネントが住むための場所であり、おそらく他の機能は含まれないでしょう。

しかし、テストをセットアップすると、次のようなテンプレートエラーが発生し、3つのコンポーネントすべてで繰り返されます。

Error: Template parse errors:
    'product-editor' is not a known element:
    1. If 'product-editor' is an Angular component, then verify that it is part of this module.
    2. If 'product-editor' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("
        <hr/>
      <product-settings></product-settings>
      [ERROR ->]<product-editor></product-editor>

子コンポーネントのモック版をロードしようとしましたが、どうすればいいかわかりません。私が見た例では、親コンポーネントをオーバーライドするだけで、子コンポーネントについては触れていません。どのようにすればよいのでしょうか。

どのように解決するのですか?

について注意すること NO_ERRORS_SCHEMA . 同じthe docsの別の部分を引用してみましょう。

NO_ERRORS_SCHEMA による浅いコンポーネントテストは、複雑なテンプレートのユニットテストを非常に単純化します。しかし、コンパイラはスペルミスやコンポーネントやディレクティブの誤用などの間違いを警告しなくなりました。

私はその欠点が、テストを書く目的にかなり反していると思います。基本的なコンポーネントをモックするのはそれほど難しくないので、なおさらです。

ここではまだ言及されていないアプローチとして、単純に設定時に宣言する方法があります。

@Component({
  selector: 'product-settings',
  template: '<p>Mock Product Settings Component</p>'
})
class MockProductSettingsComponent {}

@Component({
  selector: 'product-editor',
  template: '<p>Mock Product Editor Component</p>'
})
class MockProductEditorComponent {}

...  // third one

beforeEach(() => {
  TestBed.configureTestingModule({
      declarations: [
        ProductSelectedComponent,
        MockProductSettingsComponent,
        MockProductEditorComponent,
        // ... third one
      ],
      providers: [/* your providers */]
  });
  // ... carry on
});