java - 使用 StepScopeTestExecutionListener.class : Still getting "No Scope registered" 对 Step 作用域 Bean 进行 JUnit 测试

标签 java spring junit spring-batch spring-test

我正在尝试为“step”作用域 bean 编写一个独立的单元测试用例。我发布了这个question早些时候并了解我需要使用 StepScopeTestExecutionListener 为我的单元测试创​​建步骤范围;但是,即使使用 StepScopeTestExecutionListener 后,我仍然遇到以下异常:

Caused by: java.lang.IllegalStateException: No Scope registered for scope name 'step'
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:343)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)

我的JUnt

@TestExecutionListeners({ StepScopeTestExecutionListener.class,DependencyInjectionTestExecutionListener.class  })
@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource("classpath:properties/common.properties")
@ContextConfiguration(locations = { "/spring/common-context.xml" })
public class ConfigDAOImplTest {

    @Autowired
    private ConfigDAOImpl configDAO;

    @Spy
    private ContextParamDAO contextParamDAO = new ContextParamDAOImpl();

    private static final String SCHEMA_CONFIG = "classpath:data/CONFIG_SCHEMA.sql";
    private static final String DATA_CONFIG = "classpath:data/CONFIG_DATA.sql";

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);

        DataSource dataSource = new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript(SCHEMA_CONFIG)
                .addScript(DATA_CONFIG)
                .build();

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        //override the jdbcTemplate for the test case    
        configDAO.setJdbcTemplate(jdbcTemplate);
        configDAO.setContextParamDAO(contextParamDAO);


    }

    public StepExecution getStepExecution() {

        JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString("test", "test");
        JobParameters jobParameters = jobParametersBuilder.toJobParameters();

        JobInstance jobInstance = new JobInstance(12345L,"testJob");
        JobExecution jobExecution = new JobExecution(jobInstance,jobParameters);

        StepExecution execution = 
        MetaDataInstanceFactory.createStepExecution(jobExecution,"step",11245L);
        execution.getExecutionContext().putString("input.data", "foo,bar,spam");
        return execution;
    }
}

我可以确认,当我在 Debug模式下运行单元测试并在此方法上设置断点时,getStepExecution 确实被调用。

问题:为什么我的 JUnit 的步骤范围仍未初始化?

注意:在一个不相关的说明中,我在 getStepExecution 中手动创建 JobExecution 而不是使用 MetaDataInstanceFactory 的原因。 createJobExecution 是因为由于某种奇怪的原因,编译器能够找到 createJobExecution 方法,但在运行时找不到该方法。我使用了 -verbose:class 标志,并且可以确认只有一个 jar 可以从其中加载 MetaDataInstanceFactory 类,并且该 jar 也包含所需的方法。我假设手动创建 JobExecution 实例不应该是我的问题的根本原因。

最佳答案

该错误发生在加载测试之前,因为 common-context.xml 文件中没有定义步骤作用域 bean。由于您没有在该文件中使用批处理命名空间,因此需要手动声明步骤范围。以下是 docs 的摘录(自 3.0.10 起):

Because it is not part of the Spring container by default, 
the scope must be added explicitly, either by using the batch namespace
or by including a bean definition explicitly for the StepScope (but not both)

将以下内容添加到您的应用程序上下文中应该可以解决该问题:

<bean class="org.springframework.batch.core.scope.StepScope">
   <property name="proxyTargetClass" value="true" />
</bean>

关于java - 使用 StepScopeTestExecutionListener.class : Still getting "No Scope registered" 对 Step 作用域 Bean 进行 JUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61114625/

相关文章:

java - Hibernate可以用一个bean更新两个表吗?

grails - 在单元测试中,如何替换域对象上的接口(interface)方法?

java - 为 Java jUnit 测试创建一个 MultipartFormDataInput 对象

java - ModelAndView中重新发送请求参数

java - 如何将java文件推送和 pull 入git

java - 如何确定 OSX 硬件类型?

java - CGLIB 可以在 Android 上使用吗?

java.lang.ClassCastException : [B > cannot be cast to java. lang.String

java - Spark Web 框架单元测试

java - 位操作 : changing a single char in the binary "array"