2011-09-09 10 views
0

私の単体テストでは、テスト対象のBeanのいくつかのautowired依存関係にモックを使用したいと思います。モックが作成され、適切にユニットテストクラスに注入しますが、テスト中の豆に注入はBeanへのモック注入が失敗しました

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No matching bean of type [Service] found for 
dependency: expected at least 1 bean which qualifies as autowire candidate for this 
dependency. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)} 

で失敗しました。これは、これはの一部である

<bean id="Service" class="org.easymock.EasyMock" factory-method="createMock"> 
    <constructor-arg value="Service" ></constructor-arg> 
</bean> 

<bean id="Controller" class="Controller"> 
    <property name="Service" ref="Service"></property> 
</bean> 

私の使用testContext.xmlです配線が

@Autowired 
private Service service; 

に失敗行ってきました。しかし、私は私のユニットテストクラス(ControllerTest.java)に同じモックをautowire場合、エラーが発生していないテスト中の豆(Controller.java)、

@Autowired 
private Service service; 

注入オブジェクトは、タイプ

($Proxy18) EasyMock for interface Service 

試験下ビーンへの注入が不可能である理由を任意の提案が、試験作品への注射でありますか?

種類が ドミニク

答えて

2

に関しては、私は、この問題は、物事の順序で行う必要があるかもしれないと思います。 ControllerTestで、私はAbstractJUnit4SpringContextTestsまたはあなたの豆をすべて最初に配線しているようなもの(あなたのモックを作る機会を得る前でさえ)を伸ばしていると思います。クラス全体(または少なくともクラス宣言、setUp、tearDownおよび特定のテストメソッド)を見ることなく、言うことは難しいです。

単体テスト(統合テストとは対照的に)の通常のことは、バネで何かをまったく使用しないことです。プロパティセッターを使用してモック共同作業者を手動で注入するだけです。統合テストでは通常、モックは使用されません。モックは実際のオブジェクトを使用します。

時々、統合テストを行いたいが、実際の人が何か破壊的なことをするか、SMSメッセージなどを送信するため、特定の協力者を模擬したいと思うことがあります。私がこのような状況で行ったことは、Springが望むやり方で全てを繋ぎ、すべてがすべて初期化された後にクラス内のプロパティセッターを使って手作業で注入することです。あなたが模倣したい本当のクラスが、あなたが本当に望んでいない初期化で何かをしない限り、問題はありません。

+0

あなたのヒントをありがとう!私は、モックを使用することは春には珍しいとは思わない。ユニットテストや統合テストでは、アプリケーションのいくつかの層を嘲笑することには、多くの理由があります。しかし、あなたが正しいです、ユニットテストか統合テストが必要かどうかに注意を払うべきです。 – Dominik

+0

私はSpringアプリケーションでモックを使用することはまれであるとは思わない。 Springは実際にBeanのインスタンス化も処理するので、実際に擬似的にSpringを使用して擬似注入を行うのは珍しいと思っていました。しかし、私は私の答えからそのコメントを削除しました、率直に言って、私はそれを見たことがないので、それは珍しいことをどのように知っていますか?そんなにやるのは難しいようです。 – jhericks

+1

あなたの提案には多くの感謝があります。私はその日にそれについて多くのことを思っています。なぜそれが珍しいのでしょうか。私はすべてのSpringコンテキストリンクから単体テストを負担することになりました。今ではAbstractJUnit4SpringContextTestsから派生したものではありません...そして、それは美しく、透明性と理解しやすさがテストアーキテクチャに入りました。コントローラは独自のコンストラクタで作成され、-mocked-dependenciesはReflectionTestUtilによって設定されます@Autowiredフィールドのためのセッターの欠如)...そしてそれはうまく、ありがとう! – Dominik

1

おそらく、これはランダムな効果と関係します:SpringのBeanインスタンス化の順序。

アプリケーションコンテキスト構成の断片を見ると、Springはidサービスを持つBeanのインスタンス化がService型となることを知らないため、Service型のモックオブジェクトを最初に作成する必要があることを知る方法がありません。これにより、Controller Beanが最初に作成された場合にオートワイヤリングが行われなくなる可能性があります。これを確認する

<bean id="Controller" class="Controller" depends-on="Service"> 

(EDITを試してみてください。あなたはController.Serviceから@Autowiredを削除する場合はどうなるのサービスのためのXML設定でオートワイヤリングと明示的なプロパティを使うのか?)

@jhericksを参考にして、私たちはときどき統合テストにモックオブジェクトを挿入します(これは絶対に必要なまれなケースです):アプリケーションにオプションのパラメータ(コマンドライン、設定ファイルなど)があります)ここで追加のXMLアプリケーションコンテキスト設定文書を提供できます。この短い文書は問題のBeanのBean宣言を上書きし、それを模擬変種で置き換えます。

関連する問題