2017-05-08 6 views
1

私は、Angular 4のより大きなプロジェクトに取り組んでいます。サーバーからJSONデータを取得し、そのデータをクライアントの特別なテーブルコンポーネントに表示します。ジャスミンテストの前に構成をロードする

表の特色は、表示される列をクライアント側で定義できることです。どの列があるかを調べるには、サーバーから構成JSONファイルを取得します。私たちはこのことが一度だけ必要なので、モジュールがロードされる前に、ローディング機構をガードに配置しました。これまでのところ、これはうまく動作します。

私は2つの要求は:

  • はガードの列宣言
  • は、サーバーからデータを取得し、テーブルを埋める取得します。これはコンポーネント内で行われています

これをテストする必要があります。それが私のトラブルの始まりです。ジャスミンがユニットテストを実行する前に、JSONリクエストの列を取得できません。

fdescribe('Component: MyComponent',() => { 
    let fixture: ComponentFixture<MyComponent>; 
    let component: MyComponent; 

    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ 
     MyComponent 
     ], 
     providers: [ 
     FieldConfigurationService 
     ], 
     schemas: [NO_ERRORS_SCHEMA], 
     imports: [ 
     TranslateModule.forRoot({ 
      provide: TranslateLoader, 
      useFactory: (http: Http) => new TranslateStaticLoader(http, 'resources/i18n', '.json'), 
      deps: [Http] 
     }) 
     ] 
    }).overrideComponent(MyComponent, { 
     set: { 
     providers: [] 
     } 
    }).compileComponents() 
     .then(() => { 
     fixture = TestBed.createComponent(MyComponent); 
     component = fixture.componentInstance; 
     }); 
    })); 

    it('should create an instance',() => { 
    expect(component).toBeTruthy(); 
    }); 

    describe('when field Configuration is loaded',() => { 
    beforeEach(async(() => { 
     console.log(1); 
     component.fieldConfigurationService.loadConfiguration(true); 
     console.log(2); 
    })); 

    describe('when the component is ready for use',() => { 
     console.log(3); 
    }); 
    }); 
}); 

console.logの出力は3,1,2です。

どのようにしてcomponent.fieldConfigurationService.loadConfiguration()を配置する必要がありますか。コマンドを実行して、console.log(3)を起動してブロックを実行する前に実行するようにします。

これをテストベッドの「then」セクションに挿入しようとしました。これまでに何を行っても、データロードプロセスの非同期性のために、ユニットテストの実行は常にデータがサーバからロードされる前に開始されました。

すべてのヘルプは高く評価されています。

FieldConfigurationServiceは次のようになります。

@Injectable() 
export class FieldConfigurationService { 
    public config: any = {}; 
    public loadConfiguration(isUnitTest: boolean = false): Promise<any> { 
     return new Promise((resolve, reject) => { 
      if (isUnitTest) { 
      if (!this.config) { 
       this.config = this.readJSON('base/gulpdist/field-definition.json'); 
       resolve(this.config); 
      } else { 
       resolve(null); 
      } 
      } else { 
      if (!this.config) { 
       this.getJSON().subscribe(
       data => { 
        this.config = data; 
        resolve(data); 
       }, 
       error => reject(error) 
      ); 
      } else { 
       resolve(null); 
      } 
      } 
     }); 
    } 
    } 

    private readJSON(url) { 
     let xhr = new XMLHttpRequest(); 
     let json = null; 

     xhr.open('GET', url, false); 

     xhr.onload = function (e) { 
     if (xhr.status === 200) { 
      json = JSON.parse(xhr.responseText); 
     } else { 
      console.error('readJSON', url, xhr.statusText); 
     } 
     }; 

     xhr.onerror = function (e) { 
     console.error('readJSON', url, xhr.statusText); 
     }; 

     xhr.send(null); 
     return json; 
    } 
} 

はあなたに サイモン

答えて

1

まず非常に感謝し、これは

public loadConfiguration(isUnitTest: boolean = false): Promise<any> { 
    return new Promise((resolve, reject) => { 
     if (isUnitTest) { 

ユニットテストは、このようなあなたの実装の詳細に漏れてはならない悪い考えです。あなたはでなければなりません。は、設定データを模擬するだけです。

import { mockConfigData } from './whereever'; 

... 
const config = new FieldConfigurationService(); 
config.config = mockConfigData; 

providers: [ 
    { provide: FieldConfigurationService, useValue: config } 
] 

このように、モックファイルのある場所からモックデータを使用するようにサービスを設定しました。今、あなたは何をする必要があるかはnullを解決するポイントは何ですかresolve(null)

if (!this.config) { 
    ... 
} else { 
    resolve(null); 
} 

を固定しています。このロジックの全体的なポイントは「設定がなければそれを取り出してください。そうでなければはnullを返しますか?」。それ以外の場合は「設定を返す」べきではありませんか?だからそれを修正してください。それは同期これにより設定

if (!this.config) { 
    ... 
} else { 
    resolve(this.config); 
} 

、約束の決意を解決してくださいので、あなたは、私は非常にあなたが行うことをお勧めisUnitTestがらくたを、削除しない限り、あなたは、テストで何も変更する必要はありません。

+0

ハハハハ...ありがとう。私は単体テストに重点を置いて、FieldConfigurationServiceを完全に無視しました。それはあなたの入力のおかげで今働く。 –

関連する問題