2013-06-27 3 views
105

フォームを検証するためにプログラムで使用される単純なBeanのユニットテストを作成しようとしています。このBeanには@Componentと注釈が付けられ、クラス変数は@Value("${this.property.value}") private String thisProperty;ユニットテスト中にSpring @Valueに値を設定する

を使用していますが、可能であればプロパティファイルを使用せずにそのようにしたいと思います。この背後にある理由は、プロパティファイルから取得した値が変更された場合、テストケースに影響しないようにすることです。私のテストケースは、値そのものではなく値を検証するコードをテストすることです。

テストクラス内でJavaコードを使用してJavaクラスを初期化し、そのクラス内にSpring @Valueプロパティを設定してテストする方法はありますか?

これは近いと思われるが、まだプロパティファイルを使用しているHow Toが見つかりました。私はむしろそれがすべてJavaコードであると思います。

ありがとうございます。

答えて

88

可能であれば、私はSpring Contextなしでこれらのテストを書こうとします。あなたのテストでこのクラスを作成する場合は、そのフィールドを完全に制御できます。

@valueフィールドを設定するには、スプリングReflectionTestUtilsを使用できます。プライベートフィールドを設定する方法はsetFieldです。

@see JavaDoc: ReflectionTestUtils.setField(java.lang.Object, java.lang.String, java.lang.Object)

+1

まさに私が何をしようとしていたと私は私のクラス内の値を設定するために探していた、ありがとう! – Kyle

+1

フィールドをデフォルトアクセス(パッケージ保護)に変更して、テストに簡単にアクセスできるようにすることで、Springの依存関係をまったく使用しないことさえできます。 –

+2

例: 'org.springframework.test.util.ReflectionTestUtils.setField(classUnderTest、" field "、" value ");' – Olivier

36

あなたがしたい場合は、まだ春のコンテキスト内でテストを実行し、Spring構成クラス内の必要なプロパティを設定することができます。あなたはJUnitのを使用している場合は、SpringJUnit4ClassRunnerを使用し、そのようなあなたのテストのための専用コンフィギュレーション・クラスを定義します。

テスト中の

クラス:

@Component 
public SomeClass { 

    @Autowired 
    private SomeDependency someDependency; 

    @Value("${someProperty}") 
    private String someProperty; 
} 

テストクラス:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = SomeClassTestsConfig.class) 
public class SomeClassTests { 

    @Autowired 
    private SomeClass someClass; 

    @Autowired 
    private SomeDependency someDependency; 

    @Before 
    public void setup() { 
     Mockito.reset(someDependency); 

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

およびコンフィギュレーションクラスのこのテスト:

@Configuration 
public class SomeClassTestsConfig { 

    @Bean 
    public static PropertySourcesPlaceholderConfigurer properties() throws Exception { 
     final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer(); 
     Properties properties = new Properties(); 

     properties.setProperty("someProperty", "testValue"); 

     pspc.setProperties(properties); 
     return pspc; 
    } 
    @Bean 
    public SomeClass getSomeClass() { 
     return new SomeClass(); 
    } 

    @Bean 
    public SomeDependency getSomeDependency() { 
     // Mockito used here for mocking dependency 
     return Mockito.mock(SomeDependency.class); 
    } 
} 

これは、私はお勧めしませんこのアプローチでは、参考のためにここに追加しました。私の意見では、はるかに良い方法は、Mockitoランナーを使用することです。その場合は、Spring内でテストを実行しないでください。これははるかに明確で簡単です。

+2

私は、ほとんどのロジックをMockitoでテストする必要があることに同意します。 Springを介してテストを実行するよりも、アノテーションの存在と正確性をテストする優れた方法があることを願っています。 – Altair7852

15

これは(私はまだ短いものがいい)まだ少し冗長ものの、動作しているようです:構成でPropertyPlaceholderConfigurerを追加

@BeforeClass 
public static void beforeClass() { 
    System.setProperty("some.property", "<value>"); 
} 

// Optionally: 
@AfterClass 
public static void afterClass() { 
    System.clearProperty("some.property"); 
} 
+0

私はこの答えが賢明ではないと思うので、カスタムテストランナーを使用しなければならないときや、 '@ TestProperty'アノテーションを追加するだけのような、さまざまなシナリオでうまくいきます。 – raspacorp

4

は私のために働いています。

@Configuration 
@ComponentScan 
@EnableJpaRepositories 
@EnableTransactionManagement 
public class TestConfiguration { 
@Bean 
public DataSource dataSource() { 
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
    builder.setType(EmbeddedDatabaseType.DERBY); 
    return builder.build(); 
} 

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
    entityManagerFactoryBean.setDataSource(dataSource()); 
    entityManagerFactoryBean.setPackagesToScan(new String[] { "com.test.model" }); 
    // Use hibernate 
    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter); 
    entityManagerFactoryBean.setJpaProperties(getHibernateProperties()); 
    return entityManagerFactoryBean; 
} 

private Properties getHibernateProperties() { 
    Properties properties = new Properties(); 
    properties.put("hibernate.show_sql", "false"); 
    properties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect"); 
    properties.put("hibernate.hbm2ddl.auto", "update"); 
    return properties; 
} 

@Bean 
public JpaTransactionManager transactionManager() { 
    JpaTransactionManager transactionManager = new JpaTransactionManager(); 
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); 
    return transactionManager; 
} 

@Bean 
PropertyPlaceholderConfigurer propConfig() { 
    PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer(); 
    placeholderConfigurer.setLocation(new ClassPathResource("application_test.properties")); 
    return placeholderConfigurer; 
} 

}

および試験クラスの

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = TestConfiguration.class) 
public class DataServiceTest { 

@Autowired 
private DataService dataService; 

@Autowired 
private DataRepository dataRepository; 

@Value("${Api.url}") 
private String baseUrl; 

@Test 
public void testUpdateData() { 
    List<Data> datas = (List<Data>) dataRepository.findAll(); 
    assertTrue(datas.isEmpty()); 
    dataService.updateDatas(); 
    datas = (List<Data>) dataRepository.findAll(); 
    assertFalse(datas.isEmpty()); 
} 

}

57

スプリング4以来。1では、単体テストのクラスレベルでorg.springframework.test.context.TestPropertySource注釈を使用してコード内のプロパティ値を設定できます。それは春のコンテキストでorg.springframework.context.support.PropertySourcesPlaceholderConfigurerのインスタンスを持つことが必要だ

編集24-08-:あなたも依存Beanインスタンス

例えば

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = FooTest.Config.class) 
@TestPropertySource(properties = { 
    "some.bar.value=testValue", 
}) 
public class FooTest { 

    @Value("${some.bar.value}") 
    String bar; 

    @Test 
    public void testValueSetup() { 
    assertEquals("testValue", bar); 
    } 


    @Configuration 
    static class Config { 

    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertiesResolver() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 

    } 

} 

ノートにプロパティを注入するため、このアプローチを使用することができます2017: SpringBoot 1.4.0以降を使用している場合は、@SpringBootTest@SpringBootConfigurationの注釈でテストを初期化できます。 SpringBootの場合にはより多くの情報here

は、我々は次のコードしている

@SpringBootTest 
@SpringBootConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
@TestPropertySource(properties = { 
    "some.bar.value=testValue", 
}) 
public class FooTest { 

    @Value("${some.bar.value}") 
    String bar; 

    @Test 
    public void testValueSetup() { 
    assertEquals("testValue", bar); 
    } 

} 
+0

ありがとうございました、ついに誰かがフィールドを設定する方法ではなく値を上書きする方法に答えました。私はPostConstructの文字列フィールドから値を派生しているので、作成後ではなく、Springで設定する文字列値が必要です。 – tequilacat

+0

私は助けてうれしい –

関連する問題