Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring批处理集成测试中使用自动连线存储库?_Java_Testing_Repository_Spring Batch - Fatal编程技术网

Java 如何在Spring批处理集成测试中使用自动连线存储库?

Java 如何在Spring批处理集成测试中使用自动连线存储库?,java,testing,repository,spring-batch,Java,Testing,Repository,Spring Batch,在为Spring批处理作业编写集成测试时,我面临一些问题。主要问题是,每当在批处理作业内启动事务时,就会引发异常。 嗯,首先要做的事。想象一下,这是一个简单工作的步骤。为了简单起见,Tasklet。当然,它用于正确的批处理配置(MyBatchConfig),为了简洁起见,我也省略了它 @Component public class SimpleTask implements Tasklet { private final MyRepository myRepository;

在为Spring批处理作业编写集成测试时,我面临一些问题。主要问题是,每当在批处理作业内启动事务时,就会引发异常。
嗯,首先要做的事。想象一下,这是一个简单工作的步骤。为了简单起见,
Tasklet
。当然,它用于正确的批处理配置(
MyBatchConfig
),为了简洁起见,我也省略了它

@Component
public class SimpleTask implements Tasklet {

    private final MyRepository myRepository;

    public SimpleTask(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        myRepository.deleteAll(); // or maybe saveAll() or some other @Transactional method
        return RepeatStatus.FINISHED;
    }
}
MyRepository
是一个非常非专业的
crudepository

现在,为了测试该作业,我使用以下测试类

@SpringBatchTest
@EnableAutoConfiguration
@SpringJUnitConfig(classes = {
    H2DataSourceConfig.class, // <-- this is a configuration bean for an in-memory testing database
    MyBatchConfig.class
})
public class MyBatchJobTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;
    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;
    @Autowired
    private MyRepository myRepository;

    @Test
    public void testJob() throws Exception {
        var testItems = List.of(
            new MyTestItem(1),
            new MyTestItem(2),
            new MyTestItem(3)
        );
        myRepository.saveAll(testItems); // <--- works perfectly well
        jobLauncherTestUtils.launchJob();
    }
}
你知道为什么会这样吗


作为一种解决方法,我目前使用
@MockBean
模拟存储库,并使用
ArrayList
支持它,但我想这不是发明家的意图

有什么建议吗?
问候


更新1.1(包括解决方案)
提到的数据源配置类是

@Configuration
@EnableJpaRepositories(
        basePackages = {"my.project.persistence.repository"},
        entityManagerFactoryRef = "myTestEntityManagerFactory",
        transactionManagerRef = "myTestTransactionManager"
)
@EnableTransactionManagement
public class H2DataSourceConfig {

    @Bean
    public DataSource myTestDataSource() {
        var dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1");
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean myTestEntityManagerFactory() {
        var emFactory = new LocalContainerEntityManagerFactoryBean();
        var adapter = new HibernateJpaVendorAdapter();

        adapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
        adapter.setGenerateDdl(true);

        emFactory.setDataSource(myTestDataSource());
        emFactory.setPackagesToScan("my.project.persistence.model");
        emFactory.setJpaVendorAdapter(adapter);
        return emFactory;
    }

    @Bean
    public PlatformTransactionManager myTestTransactionManager() {
        return new JpaTransactionManager(myTestEntityManagerFactory().getObject());
    }

    @Bean
    public BatchConfigurer testBatchConfigurer() {
        return new DefaultBatchConfigurer() {
            @Override
            public PlatformTransactionManager getTransactionManager() {
                return myTestTransactionManager();
            }
        };
    }
}

默认情况下,当您在应用程序上下文中声明数据源时,Spring Batch将使用
DataSourceTransactionManager
来驱动step事务,但该事务管理器对您的JPA上下文一无所知

如果要使用另一个事务管理器,则需要覆盖
BatchConfigurer#getTransactionManager
,并返回要用于驱动step事务的事务管理器。在您的情况下,仅在应用程序上下文中声明事务管理器bean是不够的。下面是一个简单的例子:

@Bean
public BatchConfigurer batchConfigurer() {
   return new DefaultBatchConfigurer() {
      @Override
      public PlatformTransactionManager getTransactionManager() {
          return new JpaTransactionManager(myTestEntityManagerFactory().getObject());
      }
   };
}

有关更多详细信息,请参阅。

Spring批处理使用哪个事务管理器?在生产中,我没有明确配置事务管理器,但由Spring决定。在application.properties文件中,我只有一些
spring.datasource
spring.jpa.properties
属性。对于集成测试,我使用
H2DataSourceConfig
覆盖生产默认值。我已经添加了源代码。
@Bean
public BatchConfigurer batchConfigurer() {
   return new DefaultBatchConfigurer() {
      @Override
      public PlatformTransactionManager getTransactionManager() {
          return new JpaTransactionManager(myTestEntityManagerFactory().getObject());
      }
   };
}