Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpringBatchTest should support application contexts without javax.sql.DataSource #3767

Closed
qwazer opened this issue Aug 27, 2020 · 10 comments
Closed
Labels
in: test status: superseded Issues that are superseded by other issues type: enhancement

Comments

@qwazer
Copy link

qwazer commented Aug 27, 2020

Spring-batch has 2 annotations to simply context creation

EnableBatchProcessing
SpringBatchTest

EnableBatchProcessing support's app contexts without javax.sql.DataSource bean. It's mentioned in javadoc

  • If a user does not provide a {@link javax.sql.DataSource} within the context, a Map based
  • {@link org.springframework.batch.core.repository.JobRepository} will be used.

https://github.com/spring-projects/spring-batch/blob/4.2.x/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java#L88

SpringBatchTest doesn't support contexts without javax.sql.DataSource and fails with

java.lang.IllegalStateException: Failed to load ApplicationContext

	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobRepositoryTestUtils': Unsatisfied dependency expressed through method 'setDataSource' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:723)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.sp
@qwazer qwazer added the status: waiting-for-triage Issues that we did not analyse yet label Aug 27, 2020
@fmbenhassine
Copy link
Contributor

fmbenhassine commented Apr 21, 2021

I do confirm this issue, here is a failing test with v4.3.3:

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBatchTest
@RunWith(SpringRunner.class)
public class springBatchTestWithoutDataSource {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void testJob() throws Exception {
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
    }

    @Configuration
    @EnableBatchProcessing
    public static class JobConfiguration {

        @Bean
        public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
            return jobBuilderFactory.get("job")
                    .start(
                            stepBuilderFactory.get("step")
                                    .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED)
                                    .build())
                    .build();
        }
    }

}

This is not directly related to the @SpringBatchTest annotation, but rather to the way the underlying utilities it imports are designed to work (ie the JobLauncherTestUtils which autowires the job under test and JobRepositoryTestUtils which autowires a datasource). I wrote a similar comment about this in #3699 (comment). There is a similar/related open issue here: #1237.

Since the Map-based job repository has been deprecated for removal (see #3780), we need to revisit how this should work in v5 (it might be fixed by design since a datasource will be mandatory).

@fmbenhassine fmbenhassine added in: test and removed status: waiting-for-triage Issues that we did not analyse yet labels Apr 21, 2021
@fmbenhassine fmbenhassine added this to the 5.0.0 milestone Apr 21, 2021
@munnema
Copy link

munnema commented Nov 22, 2021

Hi, do we have update on this enhancement

@marschall
Copy link
Contributor

@munnema you could have a look at spring-batch-inmemory that gives you a NullDataSource, you will have to use one of the custom repositories and job explorers though.

@munnema
Copy link

munnema commented Nov 22, 2021

Hi @marschall
Thanks for getting back on query
Can I mock JobRepositoryTestUtils bean that is implicitly registered by @SpringBatchTest and couldn't see any option to exclude this bean to be registered by @SpringBatchTest, I really don't want to save and remove jobexecution.

@marschall
Copy link
Contributor

@munnema maybe it's better to raise an issue in that project and keep the discussion on this issue on topic

@fmbenhassine
Copy link
Contributor

The dependency to a datasource in JobRepositoryTestUtils was removed in #4070. As a result, SpringBatchTest should now work with a test context that does not contain a datasource.

Closing this as superseded by #4070 .

@fmbenhassine fmbenhassine closed this as not planned Won't fix, can't repro, duplicate, stale Aug 24, 2022
@fmbenhassine fmbenhassine removed this from the 5.0.0-M5 milestone Aug 24, 2022
@fmbenhassine fmbenhassine added the status: superseded Issues that are superseded by other issues label Aug 24, 2022
@oha85
Copy link

oha85 commented May 18, 2023

Hi @fmbenhassine, Is there any workaround on spring-batch 2.7.2 to unit test jobs and steps without needing DataSource ? Thank you.

@fmbenhassine
Copy link
Contributor

@oha85 This issue is closed. Please check https://github.com/spring-projects/spring-batch#getting-help for how to ask for support and I will try to help. Thank you.

@javaHelper
Copy link

No indication how to implement the test case where DataSource is used or DataSource No qualifying bean of type is coming

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test status: superseded Issues that are superseded by other issues type: enhancement
Projects
None yet
Development

No branches or pull requests

6 participants