Writing a JUnit test for a "Step" scoped bean – No scope registered for scope name "step" (Spring Batch 3.0.10)

huangapple go评论82阅读模式
英文:

Writing a JUnit test for a "Step" scoped bean - No scope registered for scope name "step" (Spring Batch 3.0.10)

问题

我想为一个作用域为 "step" 的 Spring 托管的 bean 编写一个 JUnit 测试案例。此 bean 被一个 Spring 批处理 Tasklet 引用。

configDAO ConfigDAOImpl 类的 Bean 定义

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd        
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd      
        http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <!-- bean 被定义为 "step" 作用域,因为它使用 stepExecutionContext -->
    <bean id="configDAO"
        class="com.myproject.common.dataaccess.impl.ConfigDAOImpl" scope="step">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
        <property name="corePoolSize" value="${threadpool.size}"/>
        <property name="frequency" value="#{stepExecutionContext['frequency']}" />
    </bean>
</beans>

上述 bean 的 JUnit 测试案例

@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);

        // 为测试案例重写 jdbcTemplate    
        configDAO.setJdbcTemplate(jdbcTemplate);
        configDAO.setContextParamDAO(contextParamDAO);
    }

    //.. 更多代码
}

当我运行上述测试类时,会出现以下异常:

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)

我尝试在我的测试类上方添加了 @EnableBatchProcessing 注解,但并没有解决这个问题。

我应该如何为一个 "step" 作用域的 bean 编写 JUnit 测试案例?

英文:

I want to write a JUnit test case for a Spring managed bean which has the scope as "step". This bean is refereed by a Spring Batch Tasklet.

Bean defintion for configDAO ConfigDAOImpl class

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot; xmlns:batch=&quot;http://www.springframework.org/schema/batch&quot;
    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
    xsi:schemaLocation=&quot;
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd        
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd      
        http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd&quot;&gt;

    &lt;!-- bean has been defined with a scope of &quot;step&quot; as it uses the stepExecutionContext --&gt;
    &lt;bean id=&quot;configDAO&quot;
        class=&quot;com.myproject.common.dataaccess.impl.ConfigDAOImpl&quot; scope=&quot;step&quot;&gt;
        &lt;property name=&quot;jdbcTemplate&quot; ref=&quot;jdbcTemplate&quot; /&gt;
        &lt;property name=&quot;corePoolSize&quot; value=&quot;${threadpool.size}&quot;/&gt;
        &lt;property name=&quot;frequency&quot; value=&quot;#{stepExecutionContext[&#39;frequency&#39;]}&quot; /&gt;
    &lt;/bean&gt;
&lt;/beans&gt;

JUnit test case for the above bean

@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource(&quot;classpath:properties/common.properties&quot;)
@ContextConfiguration(locations = { &quot;/spring/common-context.xml&quot; })
public class ConfigDAOImplTest {

    @Autowired
    private ConfigDAOImpl configDAO;

    @Spy
    private ContextParamDAO contextParamDAO = new ContextParamDAOImpl();

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

    @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);


    }

    //.. more coode
}

When I run the above test class, it fails with the following exception :

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

I tired added @EnableBatchProcessing annotation above my test class but that did not resolve the issue.

How can I write a JUnit test for a step scoped bean?

答案1

得分: 1

你会在官方文档中找到更多信息,有一个名为["Testing Step-Scoped Components"]的章节。但是首先,您应该使用这两个注解为您的测试添加注释(在Spring 4.1之前),以启用您的步骤范围。

@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
    StepScopeTestExecutionListener.class })

或者对于Spring 4.1+,可以使用此注解:

@SpringBatchTest

然后,您还需要定义一个StepExecution,类似于以下内容(摘自文档):

public StepExecution getStepExecution() {
        StepExecution execution = MetaDataInstanceFactory.createStepExecution();
        execution.getExecutionContext().putString("input.data", "foo,bar,spam");
        return execution;
}
英文:

You'll find more information in the official documentation, there's a section called "Testing Step-Scoped Components". But for a start you should annotate your Test with these two annotations (pre Spring 4.1) enabling your step scope.

@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
    StepScopeTestExecutionListener.class })

Or this annotation, for Spring 4.1+

@SpringBatchTest

You then also need to define a StepExecution, similar to this (and taken from the documentation)

public StepExecution getStepExecution() {
        StepExecution execution = MetaDataInstanceFactory.createStepExecution();
        execution.getExecutionContext().putString(&quot;input.data&quot;, &quot;foo,bar,spam&quot;);
        return execution;
    }

huangapple
  • 本文由 发表于 2020年4月8日 19:05:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/61099235.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定