加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 01:20:22 所属栏目:大数据 来源:网络整理
导读:我意识到最佳实践可能会建议在每个@Test方法上加载测试数据,但是这对于DBUnit而言可能会非常缓慢,因此我想出了以下解决方案,每个类只能加载一次: 每个测试类别仅加载一次数据集 支持多个数据源以及ApplicationContext中未命名为“ dataSource”的数据源 并

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

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

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

/**
 * My Test class
 */
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,DbunitLoadOnceTestExecutionListener.class})
@ContextConfiguration(locations={"classpath:resources/spring/applicationContext.xml"})
public class TestClass {

    public static final String TEST_DATA_FILENAME = "Scenario-1.xml";

    public static void beforeClassWithApplicationContext(ApplicationContext ctx) throws Exception {

        DataSource ds = (DataSource)ctx.getBean("dataSourceXyz");

        IDatabaseConnection conn = new DatabaseConnection(ds.getConnection());

        IDataSet dataSet = DbUnitHelper.getDataSetFromFile(conn,TEST_DATA_FILENAME);

        InsertIdentityOperation.CLEAN_INSERT.execute(conn,dataSet);
    }

    @Test
    public void somethingToTest() {
        // do stuff...
    }
}

/**
 * My new custom TestExecutioner
 */
public class DbunitLoadOnceTestExecutionListener extends AbstractTestExecutionListener {

    final String methodName = "beforeClassWithApplicationContext";

    @Override
    public void beforeTestClass(TestContext testContext) throws Exception {

        super.beforeTestClass(testContext);        

        Class<?> clazz = testContext.getTestClass();

        Method m = null;

        try {
            m = clazz.getDeclaredMethod(methodName,ApplicationContext.class);
        }
        catch(Exception e) {
            throw new Exception("Test class must implement " + methodName + "()",e);
        }

        m.invoke(null,testContext.getApplicationContext());
    }
}

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

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

/**
 * My Test class
 */
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,DbunitLoadOnceTestExecutionListener.class})
@ContextConfiguration(locations={"classpath:resources/spring/applicationContext.xml"})
public class TestClass {

    private static final String TEST_DATA_FILENAME = "Scenario-1.xml";

    // must be static
    private static volatile boolean isDataSetLoaded = false;

    // use the Qualifier to select a specific dataSource
    @Autowired
    @Qualifier("dataSourceXyz")
    private DataSource dataSource;

    /**
     * For performance reasons,we only want to load the DBUnit data set once per test class 
     * rather than before every test method.
     * 
     * @throws Exception
     */
    @Before
    public void before() throws Exception {

        if(!isDataSetLoaded) {

            isDataSetLoaded = true;

            IDatabaseConnection conn = new DatabaseConnection(dataSource.getConnection());

            IDataSet dataSet = DbUnitHelper.getDataSetFromFile(conn,TEST_DATA_FILENAME);

            InsertIdentityOperation.CLEAN_INSERT.execute(conn,dataSet);
        }       
    }

    @Test
    public void somethingToTest() {
        // do stuff...
    }
}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读