【问题标题】:How to have DBUnit @DatabaseSetup to happen before spring autowiring?如何在春季自动装配之前发生 DBUnit @DatabaseSetup?
【发布时间】:2013-11-26 04:03:16
【问题描述】:

考虑典型的 DBUnit Spring 测试(参见 https://github.com/springtestdbunit/spring-test-dbunit):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/META-INF/spring/applicationContext-database.xml",
"classpath:spring-*.xml"
})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    DbUnitTestExecutionListener.class })
@DatabaseSetup("/dbunit/data.xml")
public class UnitTest {

    @Autowired
    private UnitUnderTest uut;

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

我已经证实并且已经预料到,自动装配将在 DatabaseSetup 之前发生。 这必须发生,因为 DBUnit 依赖于应用程序上下文来提供配置的数据源。

问题在于 UnitUnderTest bean 有一个 @PostConstruct ,它从 DB 加载一些数据,但由于自动装配发生在 DBunit 设置之前,因此在此阶段数据将不可用。

关于如何以干净的方式解决此问题的任何想法?

【问题讨论】:

  • 这里有同样的问题。有什么解决办法吗?
  • 这确实不是一个好的解决方案,但让我继续前进。创建一个继承自要自动装配的对象的 TestClass 并公开一个用于外部初始化的方法。在@Before 测试中使用。
  • 目前没有解决方案。甚至不是一个体面的解决方法。将继续搜索。

标签: spring dbunit spring-test spring-test-dbunit


【解决方案1】:

你可以使用 Spring 的 ResourceDatabasePopulator。

我认为你可以使用这样的东西

@PostConstruct
public void myInMemryPopulator() {
final ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();

        try {

            Resource[] array = resourceResolver.getResources("classpath:/*.sql");       

            for (Resource resource : array) {

                databasePopulator.addScript(resource);
            }
            databasePopulator.populate(dataSource.getConnection());

        } catch (IOException | SQLException e) {
            LOGGER.error("Error in databasePopulator  {} ", e);
        }

    } 

【讨论】:

  • 如果这仍然没有帮助。您可以创建父测试用例并在父测试用例中添加静态块可以调用此方法
【解决方案2】:

你可以在你的测试类中有一个 setup 方法并手动调用 post 构造方法。这会起作用的。

【讨论】:

  • 恐怕那是无解的!在这种情况下,我必须将调用该方法的责任交给其他 bean。我认为没有必要这样做。我希望 spring-test-dbunit 将有一种更清洁、更少干扰的方式来测试这种场景,我相信这种情况不会那么罕见。
  • 我的 postconstruct 方法尝试检索数据库对象并在自动装配时中断,因此此解决方案无济于事。
【解决方案3】:

延迟初始化帮助了我,我在@Component* 和@Autowired 注入点上添加了@Lazy

@Lazy
@Component
public class UnitUnderTestImpl {
...
}

@Lazy
@Autowired
private UnitUnderTest uut;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-02
    • 2017-12-13
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 2013-04-26
    相关资源
    最近更新 更多