14

私には本当に奇妙に思える問題があります。私は次の設定をしています:

インターフェース:

package com.example;

public interface SomeDependency {
}

スプリングコンポーネント:

package com.example;

@Component
public class SomeClass {
}

EasyMockによって生成されたモックビーンを使用したスプリングテスト構成:

<beans ....>
    <context:component-scan base-package="com.example"/>

    <bean id="someInterfaceMock" class="org.easymock.EasyMock" factory-method="createMock">
        <constructor-arg value="com.example.SomeDependency" />
    </bean> 
</beans>

そしてユニットテスト:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/testconfig.xml")
public class SomeClassTest {

    @Autowired
    SomeClass someClass;

    @Autowired
    SomeDependency someDependency;

    @Test
    public void testSomeClass() throws Exception {
        assertNotNull(someClass);
    }

    @Test
    public void testSomeDependency() throws Exception {
        assertNotNull(someDependency);
    }
}

プロジェクトはコンパイルされ、テストは問題なく合格します。つまり、SomeClass(「実際の」オブジェクト)とSomeDependency(EasyMockによって生成されたモックオブジェクト)の両方の自動配線が成功します。

ただし、SomeClassの実装を次のように変更した場合:

@Component
public class SomeClass {

    @Autowired
    SomeDependency someDependency;
}

両方のテストが失敗するのは

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.example.SomeDependency] 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)}

だから私の質問は:

  1. SpringがSomeClassへの依存関係の自動配線に失敗するのはなぜですか( SomeClassTestへの同じ依存関係の自動配線に成功した場合)?
  2. SomeClassTestまたはtestconfig.xmlを変更して、テストに合格させるにはどうすればよいですか?

コメント:実際には、 SomeClassで表されるクラスはフレームワークの一部です。その結果、少なくとも妥当な時間内に、簡単に更新することはできません。

依存関係:

  • 春:3.0.5.RELEASE
  • EasyMock:3.0

編集:

Spring 3.2 RC1の時点で、ジェネリックファクトリメソッドとモックオブジェクトの問題が解決されました。

/マティアス

4

1 に答える 1

23

工場を使用して自動配線でBeanを作成する場合、xml内の定義の順序が実際に重要であるように思われます。someInterfaceMock上記の宣言を配置すると、component-scan機能します。

理由の説明:Springが自動配線を試みるとSomeClass、タイプのBeanが検索されますSomeDependency。この段階ではまだファクトリであるため、Springは返されるsomeInterfaceMockファクトリメソッドのシグネチャをチェックするため、 Springは必要なタイプではないもののみを検出します。EasyMock.createMock(...)<T>Object

より良い方法は、SpringのFactoryBeanインターフェースを使用してモックを作成することです。

動作するはずの基本的な実装は次のとおりです。

public class EasyMockFactoryBean<T> implements FactoryBean<T> {
    private Class<T> mockedClass;

    public void setMockedClass(Class mockedClass) {
        this.mockedClass = mockedClass;
    } 

    public T getObject() throws Exception {
        return EasyMock.createMock(mockedClass);
    }

    public Class<T> getObjectType() {
        return mockedClass;
    }

    public boolean isSingleton() {
        return true;
    } 

}

Beanの定義は次のとおりです(順序は関係ありません!):

<bean class="com.example.EasyMockFactoryBean">
    <property name="mockedClass" value="com.example.Dependancy"/>
</bean>    
于 2011-06-14T07:28:27.633 に答える