JUnit test for a Step scoped Bean using StepScopeTestExecutionListener.class : Still getting "No Scope registered"

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

JUnit test for a Step scoped Bean using StepScopeTestExecutionListener.class : Still getting "No Scope registered"

问题

我正试图为一个“步骤”作用域的bean编写独立的单元测试用例。我之前在这里发布了这个问题,并且了解到我需要使用StepScopeTestExecutionListener为我的单元测试创建一个步骤作用域;然而,即使在使用了StepScopeTestExecutionListener之后,我仍然会收到以下异常:

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

我的JUnit测试

  1. @TestExecutionListeners({ StepScopeTestExecutionListener.class,DependencyInjectionTestExecutionListener.class })
  2. @RunWith(SpringJUnit4ClassRunner.class)
  3. @PropertySource("classpath:properties/common.properties")
  4. @ContextConfiguration(locations = { "/spring/common-context.xml" })
  5. public class ConfigDAOImplTest {
  6. @Autowired
  7. private ConfigDAOImpl configDAO;
  8. @Spy
  9. private ContextParamDAO contextParamDAO = new ContextParamDAOImpl();
  10. private static final String SCHEMA_CONFIG = "classpath:data/CONFIG_SCHEMA.sql";
  11. private static final String DATA_CONFIG = "classpath:data/CONFIG_DATA.sql";
  12. @Before
  13. public void init() {
  14. MockitoAnnotations.initMocks(this);
  15. DataSource dataSource = new EmbeddedDatabaseBuilder()
  16. .setType(EmbeddedDatabaseType.H2)
  17. .addScript(SCHEMA_CONFIG)
  18. .addScript(DATA_CONFIG)
  19. .build();
  20. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  21. //override the jdbcTemplate for the test case
  22. configDAO.setJdbcTemplate(jdbcTemplate);
  23. configDAO.setContextParamDAO(contextParamDAO);
  24. }
  25. public StepExecution getStepExecution() {
  26. JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
  27. jobParametersBuilder.addString("test", "test");
  28. JobParameters jobParameters = jobParametersBuilder.toJobParameters();
  29. JobInstance jobInstance = new JobInstance(12345L,"testJob");
  30. JobExecution jobExecution = new JobExecution(jobInstance,jobParameters);
  31. StepExecution execution =
  32. MetaDataInstanceFactory.createStepExecution(jobExecution,"step",11245L);
  33. execution.getExecutionContext().putString("input.data", "foo,bar,spam");
  34. return execution;
  35. }
  36. }

我可以确认getStepExecution确实被调用了,因为我在这个方法上设置了断点,然后以调试模式运行了单元测试。

问题:为什么步骤作用域仍然没有初始化我的JUnit?

**注意:**无关的是,我在getStepExecution内部手动创建JobExecution,而不是使用MetaDataInstanceFactory.createJobExecution的原因是,出于一些奇怪的原因,编译器能够找到createJobExecution方法,但在运行时找不到该方法。我使用了-verbose:class标志,可以确认只有一个包含MetaDataInstanceFactory类的jar被加载,而且该jar也包含所需的方法。我假设手动创建JobExecution实例不应该是我的问题的根本原因。

英文:

I am trying to write an independent unit test case for a "step" scoped bean. I posted this question earlier and understand that I need to use a StepScopeTestExecutionListener to create a step scope for my unit test; however, I still get the following exception even after using the StepScopeTestExecutionListener :

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

My JUnt

  1. @TestExecutionListeners({ StepScopeTestExecutionListener.class,DependencyInjectionTestExecutionListener.class })
  2. @RunWith(SpringJUnit4ClassRunner.class)
  3. @PropertySource("classpath:properties/common.properties")
  4. @ContextConfiguration(locations = { "/spring/common-context.xml" })
  5. public class ConfigDAOImplTest {
  6. @Autowired
  7. private ConfigDAOImpl configDAO;
  8. @Spy
  9. private ContextParamDAO contextParamDAO = new ContextParamDAOImpl();
  10. private static final String SCHEMA_CONFIG = "classpath:data/CONFIG_SCHEMA.sql";
  11. private static final String DATA_CONFIG = "classpath:data/CONFIG_DATA.sql";
  12. @Before
  13. public void init() {
  14. MockitoAnnotations.initMocks(this);
  15. DataSource dataSource = new EmbeddedDatabaseBuilder()
  16. .setType(EmbeddedDatabaseType.H2)
  17. .addScript(SCHEMA_CONFIG)
  18. .addScript(DATA_CONFIG)
  19. .build();
  20. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  21. //override the jdbcTemplate for the test case
  22. configDAO.setJdbcTemplate(jdbcTemplate);
  23. configDAO.setContextParamDAO(contextParamDAO);
  24. }
  25. public StepExecution getStepExecution() {
  26. JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
  27. jobParametersBuilder.addString("test", "test");
  28. JobParameters jobParameters = jobParametersBuilder.toJobParameters();
  29. JobInstance jobInstance = new JobInstance(12345L,"testJob");
  30. JobExecution jobExecution = new JobExecution(jobInstance,jobParameters);
  31. StepExecution execution =
  32. MetaDataInstanceFactory.createStepExecution(jobExecution,"step",11245L);
  33. execution.getExecutionContext().putString("input.data", "foo,bar,spam");
  34. return execution;
  35. }
  36. }

I can confirm that the getStepExecution does get called as I ran the unit test in debug mode with a breakpoint on this method.

Question : Why is the step scope still not getting initialized for my JUnit?

Note: On an unrelated note, the reason why I am manually creating a JobExecution inside getStepExecution instead of using MetaDataInstanceFactory.createJobExecution is because for some weird reason, the compiler is able to find the createJobExecution method but the method is not found at runtime. I used the -verbose:class flag and can confirm that there is only one jar from where the MetaDataInstanceFactory class gets loaded and that jar contains the required method as well. I am assuming that manually creating a JobExecution instance should not be the root cause of my issue.

答案1

得分: 3

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

  1. 因为它默认不是 Spring 容器的一部分,作用域必须显式地添加,
  2. 可以通过使用批处理命名空间或者为 StepScope 显式地包含一个 bean 定义来实现(但不能同时使用两者)。

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

  1. <bean class="org.springframework.batch.core.scope.StepScope">
  2. <property name="proxyTargetClass" value="true" />
  3. </bean>
英文:

The error happens before even loading your test, since there is no step scope bean defined in your common-context.xml file. Since you are not using the batch namespace in that file, you need to declare the step scope manually. Here is an excerpt from the docs (of 3.0.10):

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

Adding the following to your application context should fix the issue:

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

huangapple
  • 本文由 发表于 2020年4月9日 13:39:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/61114625.html
匿名

发表评论

匿名网友

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

确定