web-dev-qa-db-ja.com

単体テストで自動配線されたBeanをオーバーライドする

特定の単体テストで自動配線されたBeanを簡単にオーバーライドできる簡単な方法はありますか?コンパイルクラスにはすべてのタイプのBeanが1つしかないため、この場合の自動配線の問題はありません。テストクラスには追加のモックが含まれます。単体テストを実行するとき、基本的に言う追加の構成を指定したいだけです。この単体テストの実行中は、標準Beanの代わりにこのモックを使用します。

プロファイルは、私が必要とするものに対して少し過剰に見えるようであり、異なる単体テストが異なるモックを持つ可能性があるため、これがプライマリアノテーションで達成可能かどうかはわかりません。

48
samblake

テストで単に別のBeanを提供したいだけなら、スプリングプロファイルやmockitoを使用する必要はないと思います。

以下を実行してください。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { TestConfig.class })
public class MyTest
{
    @Configuration
    @Import(Application.class) // the actual configuration
    public static class TestConfig
    {
        @Bean
        public IMyService myService()
        {
            return new MockedMyService();
        }
    }

    @Test
    public void test()
    {
        ....
    }
}

注:スプリングブート1.3.2 /スプリング4.2.4でテスト済み

71
teo

Spring Boot 1.4では、それを行う簡単な方法があります:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MyApplication.class })
public class MyTests {
    @MockBean
    private MyBeanClass myTestBean;

    @Before
    public void setup() {
         ...
         when(myTestBean.doSomething()).thenReturn(someResult);
    }

    @Test
    public void test() {
         // MyBeanClass bean is replaced with myTestBean in the ApplicationContext here
    }
}
43

私は同様の問題を抱えていましたが、ミックスで解決しましたが、これはより便利で再利用可能です。テスト用のスプリングプロファイルと、モックするBeanを非常に簡単な方法でオーバーライドする構成クラスを作成しました。

@Profile("test")
@Configuration
@Import(ApplicationConfiguration.class)
public class ConfigurationTests {

    @MockBean
    private Producer kafkaProducer;

    @MockBean
    private SlackNotifier slackNotifier;

}

それにより、これらのモックBeanを@Autowireし、mockitoを使用してそれらを検証できます。主な利点は、すべてのテストがテストごとに変更することなく、モックBeanをシームレスに取得できることです。テスト済み:

スプリングブーツ1.4.2

6

さまざまなコンテキストで使用するBeanの種類を知るには、スプリングプロファイルを使用する必要があります。

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html

1
Eddú Meléndez

Mats.nowakがコメントしたように、@ContextConfigurationはこれに役立ちます。

親テストクラスは次のようなものだとしましょう:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/some-dao-stuff.xml"
    ,"classpath:spring/some-rest-stuff.xml"
    ,"classpath:spring/some-common-stuff.xml"
    ,"classpath:spring/some-aop-stuff.xml"
    ,"classpath:spring/some-logging-stuff.xml"
    ,"classpath:spring/some-services-etc.xml"
})
public class MyCompaniesBigTestSpringConfig {
...

子テストクラスを作成します。

package x.y.z;
@ContextConfiguration
public class MyOneOffTest extends MyCompaniesBigTestSpringConfig {
...

src/test/resources/x/y/z/MyOneOffTest-context.xmlに配置します

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <bean id="widgetsService" class="com.mycompany.mydept.myservice.WidgetsService" primary="true" />

</beans>

そのwidgetsService Beanは、メイン構成xml(またはJava config)で定義されたBeanをオーバーライド(代わりに)します。 inheritLocations を参照してください。デフォルトの-context.xmlファイルにも注意してください。その例 here 。更新:primary="true"を追加する必要がありましたが、明らかに必要です。

0
awgtek