2015-06-23 21 views
0

我有一个tasklet一个JUnit测试,它是这样的:在Junit测试中检索上下文值。

@ContextConfiguration(locations = {"/context/job-runner-context.xml"}) 
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class }) 
@RunWith(SpringJUnit4ClassRunner.class) 
public class InicializaTaskletTest extends BaseTeste { 

    @Resource 
    private ChunkContext chunkContext; 


    @Before 
    public void setUp() throws Exception { 

    } 

    @Test 
    public void testExecutaTaskletInicializacao() throws Exception { 
     AtividadesContext atividadesContext = create(); 
     ExecutionContext ctx = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext(); 
     ctx.put(ATIVIDADES_FOLHA, atividadesContext); 
     when(service.criarArquivo(diretorio, atividadesContext)).thenReturn(new Emissao(); 
     RepeatStatus retorno = tasklet.execute(mock(StepContribution.class), chunkContext); 
    } 

} 

在我想回到一个emissao对象当我打电话service.criarArquivo与“diretorio”和“atividadesContext”参数的微进程。

的微进程是这样​​的:

@Value("#{jobExecutionContext['atividadesFolha']}") 
private AtividadesContext atividadesContext; 

@Override 
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws IOException, AtividadeJaIniciadaException { 
    EmissaoArquivoSpai emissao = arquivoSpaiService.criarArquivo(diretorioBaseArquivo, atividadesContext); 

    return RepeatStatus.FINISHED; 
} 

}

问题是,当我执行JUnit测试atividadesContext的注射无效或无法可正确的背景下提出。而测试的when子句返回一个null emissao对象,因为它不是方法期望的参数。我可以使用Mockito.any()来做到这一点,但首先我想明白为什么我不能在junit测试中注入上下文对象。

当我以正常的方式运行作业时,我可以正常注入atividadesContext。

回答

1

在Spring批处理单元测试中,我们使用一个名为JobSynchronizationManager的组件(该步骤同样也有)。在致电您的作业范围的bean之前,您将JobExecution注册为JobSynchronizationManager。这使得它可以通过ApplicationContext进行接线。

所以在看你的测试,你会构建它像如下:

@Test 
public void testExecutaTaskletInicializacao() throws Exception { 
    AtividadesContext atividadesContext = create(); 

    JobExecution jobExecution = new JobExecution(5l); 
    ExecutionContext ctx = new ExecutionContext(); 
    ctx.put(ATIVIDADES_FOLHA, atividadesContext); 
    jobExecution.setExecutionContext(ctx); 

    JobSynchronizationManager.register(jobExecution); 

    when(service.criarArquivo(diretorio, atividadesContext)).thenReturn(new Emissao()); 
    RepeatStatus retorno = tasklet.execute(mock(StepContribution.class), chunkContext); 

    JobSynchronizationManager.release(); 
} 

你可以阅读更多有关文件在这里JobSynchronizationManagerhttp://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/scope/context/JobSynchronizationManager.html

+0

有另一种解决方案?我们的项目使用SpringBatch 2.1.9。从3.0开始,我看到JobSynchronizationManager在库API中。 – alexpfx

+0

使用Step版本('StepSynchronizationManager')来执行有步骤限定范围的bean。 –