2017-11-16 13 views
1

こんにちは、私は書き込むモジュールのためにJestでいくつかのユニットテストを書こうとしていますが、現在固執しています。ユニットテストで関数が呼び出されたかどうかを確認してください

export const submitOrder = async (body, key) => { 
    const clientRepo = new ClientRepository(db) 
    const companyRepo = new CompanyRepository(db) 

    const company = await getCompanyByKey(
    companyRepo, 
    key 
); 

    const client = await createClient(
    clientRepo, 
    body 
); 

    await addClientToCompany(
    companyRepo, 
    client.id, 
    company.id 
); 

    .. More things 
} 

Iは容易モックリポジトリをダウン渡すことによって(getCompanyByKeycreateClient & addClientToCompany)の各機能をテストすることができます。

しかし、submitOrder関数の "flow"を、私のリポジトリ関数が呼び出されたかどうかを調べることによってテストしたいと思います。しかし、私はそれぞれのリポジトリのインスタンスが必要になります。私はsubmitOrderの機能までインスタンス化しません。

私のユニットテストの機能と似たようなものです。

jest.mock('../repositories/ClientRepository'); 
jest.mock('../repositories/CompanyRepository'); 

test('should be able to submit an order', async() => { 
    const apiKey = 'mocked-super-key'; 
    const body = getMockData(); 

    const result = await submitOrder(body, apiKey); 
    expect(result).toMatchSnapshot(); 
    expect(CompanyRepository.findByKey).toHaveBeenCalled(); 
    expect(ClientRepository.create).toHaveBeenCalled(); 
    expect(CompanyRepository.addClient).toHaveBeenCalled(); 
}); 

あなたは私のリポジトリが呼び出された場合、私はテストする方法の任意のヒントを持っていますか?

答えて

1

あなたが記述した問題は、依存性注入の背後にある動機付け要因の1つです。

単一の例として、submitOrder()コードではnewを使用して、特定の実装ClientRepositoryのクライアントリポジトリを直接インスタンス化します。代わりに、依存関係があることを宣言することができます。クライアントリポジトリのインタフェースを実装するオブジェクトが必要です。それは、そのようなオブジェクトが周囲の環境(流行語の「依存性注入コンテナ」)によって供給されることを可能にします。次に、テスト中に実際の実装ではなく模擬実装を作成して提供します。

これには、複数の「本当の」実装の中から選択できる必要がある場合は、すでに実装されているという利点もあります。

これを達成する方法はたくさんあります。これは、デザインパターンと同じくらいシンプルにすることも、より完全なソリューションのために依存性注入フレームワークを使用することもできます。

この練習のためにコードをリファクタリングできない場合、JavaScriptは動的であるため、おそらくnewの呼び出しを傍受し、それによって依存性注入をシミュレートする方法を組み合わせることができます。

+0

確かに、私はあなたを理解していると思います。何かのように: 'container.register( 'companyRepository'、new CompanyRepository())'? テストスイートで同じですが 'container.register( 'companyRepository'、新しいMockCompanyRepository())を実行すると、私の疑似文を上書きしませんか? – mertje

+0

私は、container.register( 'companyRepository'、新しいCompanyRepository())がどこで起こるかということについて、矛盾した前提を作っていると思います。テスト中に決して実行されない行です。 –

+0

そう、私はいくつかの設定ファイルが依存関係を必要とし、どの環境(生産とテスト)を指しているのでしょうか? – mertje

1

第2パラメータとして模擬実装ファクトリをjest.mock,as described in the docsに渡すことができます。

これを使用して、チェックしたいメソッドを呼び出すことができます。

このお試しください:CompanyRepositoryが「新しい」を使用して作成されているので、我々はこのケースでは、クラス定義を使用し、「作成」メソッドが呼び出されたときに呼び出され、モック関数を渡し

jest.mock('../repositories/CompanyRepository',() => { 
    findByKey: jest.fn(), 
    addClient: jest.jn() 
}); 

const mockCreate = jest.fn(); 

jest.mock('../repositories/CompanyRepository',() => class { 
    create(...args) { 
     mockCreate(...args); 
    } 
}); 

test('should be able to submit an order', async() => { 
    const apiKey = 'mocked-super-key'; 
    const body = getMockData(); 

    const result = await submitOrder(body, apiKey); 
    expect(result).toMatchSnapshot(); 
    expect(CompanyRepository.findByKey).toHaveBeenCalled(); 
    expect(ClientRepository.create).toHaveBeenCalled(); 
    expect(CompanyRepository.addClient).toHaveBeenCalled(); 
}); 

を。

+0

残念ながら、私の 'CompanyRepository'が__new__キーワードでインスタンス化されているので、これはうまくいきません。 mimic mockを '__mock__'フォルダに作成して置き換えることはできますが、しかし、私はまだ私のリポジトリ機能をテストできません。 – mertje

+0

OK、モックファクトリでクラスを返すこともできます。私のコード例を更新しました。試してみてください。 –

関連する問題