72

単体テストを実行すると、スケジュールされたタスクが呼び出されます。この動作を防ぎたいのですが、これは@EnableSchedulingメインのアプリ構成にあるという事実が原因です。

単体テストでこれを無効にするにはどうすればよいですか?

プロファイルの設定を提案する この質問/回答に出くわしましたか?

どうすればいいかわからない?またはそのやり過ぎの場合は?単体テスト用に別の AppConfiguration を用意することを考えていましたが、それを行うとコードを 2 回繰り返すように感じますか?

@Configuration
@EnableJpaRepositories(AppConfiguration.DAO_PACKAGE)
@EnableTransactionManagement
@EnableScheduling
@ComponentScan({AppConfiguration.SERVICE_PACKAGE,
                AppConfiguration.DAO_PACKAGE,
                AppConfiguration.CLIENT_PACKAGE,
                AppConfiguration.SCHEDULE_PACKAGE})
public class AppConfiguration {

    static final    String MAIN_PACKAGE             = "com.etc.app-name";
    static final    String DAO_PACKAGE              = "com.etc.app-name.dao";
    private static  final  String ENTITIES_PACKAGE  = "com.etc.app-name.entity";
    static final    String SERVICE_PACKAGE          = "com.etc.app-name.service";
    static final    String CLIENT_PACKAGE           = "com.etc.app-name.client";
    static final    String SCHEDULE_PACKAGE         = "com.etc.app-name.scheduling";


    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
       // stripped code for question readability
    }

    // more app config code below etc

}

単体テストの例。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={AppConfiguration.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
@WebAppConfiguration
public class ExampleDaoTest {

    @Autowired
    ExampleDao exampleDao;

    @Test
    public void testExampleDao() {
        List<Example> items = exampleDao.findAll();
        Assert.assertTrue(items.size()>0);
    }
}
4

9 に答える 9

17

別の方法は、イベントをスケジュールする Bean ポスト プロセッサの登録を解除することです。これは、テストのクラスパスに次のクラスを配置するだけで実行できます。

public class UnregisterScheduledProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
        for (String beanName : beanFactory.getBeanNamesForType(ScheduledAnnotationBeanPostProcessor.class)) {
            ((DefaultListableBeanFactory)beanFactory).removeBeanDefinition(beanName);
        }
    }
}

これは非常に単純で、仕事をしているように見えますが、これをあまりテストしていないことに注意してください。定義された Bean をレジストリから削除したり、PostProcessors の順序が問題にならないことを確認したりすることの影響を確認してください...

于 2017-01-10T10:58:05.923 に答える
2

各テストで、使用するスプリング構成を定義します。現在、次のものがあります。

@ContextConfiguration(classes={AppConfiguration.class})

一般的な方法は、通常のアプリケーションとテスト用に別々のスプリング構成を定義することです。

AppConfiguration.java 
TestConfiguration.java

TestConfiguration次に、テストでは、現在のAppConfiguration使用の代わりに参照するだけです@ContextConfiguration(classes={TestConfiguration.class})

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfiguration.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
@WebAppConfiguration
public class ExampleDaoTest

このようにして、本番コードとは異なる方法でテストの設定を構成できます。たとえば、通常のデータベースの代わりにインメモリ データベースをテストに使用できます。

于 2015-03-12T16:20:00.777 に答える