4

まず、プライベート メソッドをテストするべきではないことは理解していますが、プライベート メソッドが何らかのロジックに基づいて呼び出されたかどうかをテストする必要がある場合があると感じています。

すべての http リクエストにコードを書き込むことなくグローバル エラー処理を実行できるように、angular 2 http サービスのラッパー サービスを構築しています。

クラスの小さなサンプルは次のようになります。

export class ApiService {
  constructor(private http: Http, private error: Error, private apiConfig: ApiConfig) {}

  public get(url: string, options: RequestOptionsArgs={}): Observable<any> {
   return this.http.get(url, options).catch((error: any) => {
     this.error.dispatch(error);
     return error;
   });
  }
}

get メソッドをテストし、Error 応答でモック応答をテストして、catch が発生するようにしたい場合、これはプライベートであるため、error.dispatch メソッドが呼び出されたかどうかをテストできません。プライベート メソッドをスパイできません。

「キャッチ」が起動されていることをテストしているだけであり、明らかにその内部のメソッドが起動する場合は、http サービス自体をテストしているだけだと主張することもできます。「catch」が発生した場合は error.dispatch が呼び出しとして追加され、何らかの理由で別の開発者によって削除された場合は失敗することを確認したい。多分これはそれをテストする悪い方法ですか?私は他の提案を受け入れます。

次のようにプライベート クラスをモックできます。

{ provide: Error, useClass: FakeError }

しかし、ApiService クラスの設計図は同じままであり、現在の FakeError サービスはまだ非公開です。Java では、自分でインスタンスを作成し、それを注入できます。それを所有しているため、アクセスできます。私はjasmine/typescript/angular2でそれを行う方法を見つけようとしていると思います??

4

1 に答える 1

6

ここでスパイが役に立ちます。DIなしで実数Errorをインスタンス化できる場合は、次のことができます

let error;
beforeEach(()=>{
   error = new Error();
   spyOn(error, 'dispatch');

  TestBed.configureTestingModule({
    providers: [
      { provide: Error, useValue: error }
    ]
  });
});

it('', ()=> {
  expect(error.dispatch).toHaveBeenCalled();
});

または、クラスを忘れてErrorモックを提供することもできます。

class FakeError {
  dispatch = jasmine.createSpy('dispatch');
}

上記のように使用するだけです。ただし、上記のように呼び出す必要はありませんspyOn。ここでdispatchは、すでにスパイです。

于 2016-09-21T18:18:23.553 に答える