您能想到一种更好的方法,即使用Spring在每个测试类中仅加载一次DBbUnit吗?

前端之家收集整理的这篇文章主要介绍了您能想到一种更好的方法,即使用Spring在每个测试类中仅加载一次DBbUnit吗? 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我意识到最佳实践可能会建议在每个@Test方法上加载测试数据,但是这对于DBUnit而言可能会非常缓慢,因此我想出了以下解决方案,每个类只能加载一次:

>每个测试类别仅加载一次数据集
>支持多个数据源以及ApplicationContext中未命名为“ dataSource”的数据源
>并非严格要求回滚插入的DBUnit数据集

虽然下面的代码有效,但令我感到困扰的是我的Test类在类ClassClassApplicationApplicationContext()之前有静态方法,但由于它是静态的,所以不能属于接口.因此,以非类型安全的方式使用我对Reflection的使用.有没有更优雅的解决方案?

  1. /**
  2. * My Test class
  3. */
  4. @RunWith(SpringJUnit4ClassRunner.class)
  5. @TestExecutionListeners({DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,DbunitLoadOnceTestExecutionListener.class})
  6. @ContextConfiguration(locations={"classpath:resources/spring/applicationContext.xml"})
  7. public class TestClass {
  8. public static final String TEST_DATA_FILENAME = "Scenario-1.xml";
  9. public static void beforeClassWithApplicationContext(ApplicationContext ctx) throws Exception {
  10. DataSource ds = (DataSource)ctx.getBean("dataSourceXyz");
  11. IDatabaseConnection conn = new DatabaseConnection(ds.getConnection());
  12. IDataSet dataSet = DbUnitHelper.getDataSetFromFile(conn,TEST_DATA_FILENAME);
  13. InsertIdentityOperation.CLEAN_INSERT.execute(conn,dataSet);
  14. }
  15. @Test
  16. public void somethingToTest() {
  17. // do stuff...
  18. }
  19. }
  20. /**
  21. * My new custom TestExecutioner
  22. */
  23. public class DbunitLoadOnceTestExecutionListener extends AbstractTestExecutionListener {
  24. final String methodName = "beforeClassWithApplicationContext";
  25. @Override
  26. public void beforeTestClass(TestContext testContext) throws Exception {
  27. super.beforeTestClass(testContext);
  28. Class<?> clazz = testContext.getTestClass();
  29. Method m = null;
  30. try {
  31. m = clazz.getDeclaredMethod(methodName,ApplicationContext.class);
  32. }
  33. catch(Exception e) {
  34. throw new Exception("Test class must implement " + methodName + "()",e);
  35. }
  36. m.invoke(null,testContext.getApplicationContext());
  37. }
  38. }

我曾经想到的另一种想法可能是创建一个静态单例类,以保存对ApplicationContext的引用,并从DbunitLoadOnceTestExecutionListener.beforeTestClass()填充它.然后,我可以从TestClass上定义的标准@BeforeClass方法中检索该单例引用.我上面调用每个TestClass的代码看起来有些混乱.

最佳答案
在得到Matt和JB的有益反馈之后,这是实现所需结果的简单得多的解决方

  1. /**
  2. * My Test class
  3. */
  4. @RunWith(SpringJUnit4ClassRunner.class)
  5. @TestExecutionListeners({DependencyInjectionTestExecutionListener.class,DbunitLoadOnceTestExecutionListener.class})
  6. @ContextConfiguration(locations={"classpath:resources/spring/applicationContext.xml"})
  7. public class TestClass {
  8. private static final String TEST_DATA_FILENAME = "Scenario-1.xml";
  9. // must be static
  10. private static volatile boolean isDataSetLoaded = false;
  11. // use the Qualifier to select a specific dataSource
  12. @Autowired
  13. @Qualifier("dataSourceXyz")
  14. private DataSource dataSource;
  15. /**
  16. * For performance reasons,we only want to load the DBUnit data set once per test class
  17. * rather than before every test method.
  18. *
  19. * @throws Exception
  20. */
  21. @Before
  22. public void before() throws Exception {
  23. if(!isDataSetLoaded) {
  24. isDataSetLoaded = true;
  25. IDatabaseConnection conn = new DatabaseConnection(dataSource.getConnection());
  26. IDataSet dataSet = DbUnitHelper.getDataSetFromFile(conn,TEST_DATA_FILENAME);
  27. InsertIdentityOperation.CLEAN_INSERT.execute(conn,dataSet);
  28. }
  29. }
  30. @Test
  31. public void somethingToTest() {
  32. // do stuff...
  33. }
  34. }

类DbunitLoadOnceTestExecutionListener不再需要,已被删除.它只是表明,阅读所有奇特的技巧有时可能会使您自己的判断蒙蔽:o)

猜你在找的Spring相关文章