2017-03-02 16 views
7

@Primaryを使用してテストコンフィグレーションで宣言されたテスト中にSpring Beanをオーバーライドしようとしています。 1つの宣言はsrc/main/javaパスにあり、もう1つはsrc/test/javaパスにあります。SpringはプライマリBeanを非プライマリBeanでオーバーライドします

しかし、Springは意図的にプライマリBeanを非プライマリBeanに置き換えています。私はテストに使用したくないものです。本番(src/main/java)構成Beanをコメントアウトするだけで、必要に応じてテスト構成内の1次テスト(src/main/test)Beanが使用されます。 (明らかに私は、テストを実行するたびにコードをコメントアウトすることはできません。)ログから

osbfsDefaultListableBeanFactory - 異なる定義でBeanの「sqsConnectionFactory」Bean定義をオーバーライド:置き換え [ルートBean:クラス[null];スコープ=;抽象的な=偽; lazyInit = false; autowireMode = 3; dependencyCheck = 0; autowireCandidate = true; プライマリ=真; factoryBeanName = testJmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = null; destroyMethodName =(推論);クラスパスリソース[COM/FOO /構成/ TestJmsConfiguration.class]

[ルート豆:クラス[NULL]で定義されます。スコープ=;抽象的な=偽; lazyInit = false; autowireMode = 3; dependencyCheck = 0; autowireCandidate = true; プライマリ=偽; factoryBeanName = jmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = null; destroyMethodName =(推論);クラスパスリソースに定義されている[COM/fooの/設定/ JmsConfiguration.class]]

なぜ春は、非プライマリ豆を主な豆を交換して、どのように、具体的としてマークされたBeanを使用するように春、私は入手できますか主な豆?

編集: のsrc /メイン/ javaの構成:

@Configuration 
public class JmsConfiguration { 

... other bean declarations here ... 

@Bean 
public SQSConnectionFactory sqsConnectionFactory(Region region) throws JMSException { 
    return SQSConnectionFactory.builder() 
      .withRegion(region) 
      .build(); 
} 
} 

試験構成:

@RunWith(SpringRunner.class) 
@SpringBootTest 
@ActiveProfiles(profiles = {"test"}) 
+0

問題のあるテスト設定とテストクラスを追加してください。 – reos

+2

同じ名前のBeanを作成する2つの異なるメソッド。その結果、動作が発生する可能性があります。 @Bean(name = "nameforbean") – alfcope

+0

@alfcopeこれは答えです、ありがとう!これを回答として提出すれば、私はそれを正しいと認めます。私は、なぜプライマリとマークされたBeanをプライマリとマークされていないものに置き換えているかを知っているとき、Springがその動作を許可する理由を知らない。 – FiguringThisOut

答えて

2

@Primaryが場合が、唯一の注入点で有効となります異なる豆が注入される状態と一致し、決定がなされる必要があるので、競合である。

@Primaryは、Beanの初期化時に使用されません。同じBeanを作成する2つの異なるメソッドを使用していて、それらの名前を指定していない場合、Springはそれをオーバーライドしようとしていると考えているため、この動作が発生する可能性があります。与えられた名前がもっとも簡単な解決策ですが、あなたのコンテキストはまだ使用したくないBeanを初期化することに注意してください。

+1

ソリューションと説明をありがとうございます。 – FiguringThisOut

0

@Configuration 
public class TestJmsConfiguration { 

@Bean(name="messageProducerMock") 
public MessageProducer mockMessageProducer() { 
    return new MessageProducerMock(); 
} 

... other bean declarations here ... 

@Bean 
@Primary 
public SQSConnectionFactory sqsConnectionFactory(@Qualifier("messageProducerMock") MessageProducer messageProducerMock) throws JMSException { 
    ... returning setup mock here 
} 
} 

クラスのテストでは、と注釈されています私はあなたのテストに@ContextConfigurationが足りないかもしれないと思うクラス。テストコンフィギュレーションクラスの

例(SRC /試験/ジャワ/ TestConfiguration.class):

@Configuration 
@ComponentScan 
public class TestConfiguration { 
    @Bean 
    RabbitSender rabbitSender() { 
     return mock(RabbitSender.class); 
    } 

} 

テストクラスの例:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = TestConfiguration.class) 
public class SomeServiceTest { 

} 
+0

現在の構成では、プライマリBeanが必要に応じてロードされています。非プライマリBeanがそれを置き換えているだけです。 @ContextConfigurationを手作業で追加するのはどういうのですか?プライマリBeanの代わりに他のBean宣言があるため、このBeanを含む他のコンフィグレーションクラスが必要です。 – FiguringThisOut

+0

このようなことをすれば、@Primaryを書く必要はありません。 TestConfigurationクラスのBeanは「プライマリ」Beanをオーバーライドします。この注釈は、特定のテストに特定の構成を使用することをSpringに指示するため、他のテストより優先されます。 – hya

関連する問題