0

I am trying to execute DAO tests, so i want Spring Boot to build the implementations, so i have this test:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = FakeServiceRunner.class)
public class ClientDAOTests {

    @Autowired
    private ClientDAO dao;

    @Test
    public void testFindAllClients() {
        ....
        Page<Client> clients = this.dao.findAll(new PageRequest(0, 30, null));
        // Asserts..
    }
}

This is my FakeServiceRunner. I called it like this because this is not the real class i am running to run the service, (i haven't got access to that class), so i build this "FakeServiceRunner", to have all Spring Boots features. So this is that class:

@SpringBootApplication
@Import({ServicesConfiguration.class})
public class FakeServiceRunner {

    public static void main(String[] args) {
        SpringApplication.run(FakeServiceRunner.class, args);
    }

}

And my ServicesConfiguration:

    @Configuration
    @Import({PersistenceConfiguration.class, TransformersConfiguration.class})
    public class ServicesConfiguration {

        @Autowired
        private ClientDAO clientDAO; //Comes from PersistenceConfiguration

        @Autowired
        @Qualifier("domainMapper")
        private MapperFacade mapper; //Comes from TransfomersConfiguration

        @Bean
        @Scope(BeanDefinition.SCOPE_PROTOTYPE)
        public ClientService clientService() {
            ClientServiceImpl clientService = new ClientServiceImpl(this.clientDAO);
            clientService.setMapper(this.mapper);
            return clientService;
        }

    }

And finally, my ClientServiceImpl class:

@Service
public class ClientServiceImpl
    implements ClientService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientServiceImpl.class);

    private ClientDAO dao;
    private MapperFacade mapper;

    public ClientServiceImpl(ClientDAO dao) {
        this.dao = dao;
    }

    public void setMapper(MapperFacade mapper) {
        this.mapper = mapper;
    }

    // Service methods...
}

So i put breakpoints in constructor and also in clientService method (in ServicesConfiguration.class), and runned it in Debug, and it didn't join in any of these breakpoints.

Do you know what is going on? Regards.


EDIT

Sorry, i've totally forgotten to put the exception :P here it is :

ERROR (TestContextManager.java:215) - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@4a8f5f75] to prepare test instance [com.example.movies.domain.ClientDAOTests@1be0c344]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientServiceImpl' defined in file [/home/despubuntu/Documents/Workspace/example-backend-development/example-backend-development/example-backend-development-domain/target/classes/com/example/movies/domain/feature/client/service/ClientServiceImpl.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.movies.domain.feature.client.service.ClientServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.example.movies.domain.feature.client.service.ClientServiceImpl.<init>()
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1101)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:100)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    ... 25 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.movies.domain.feature.client.service.ClientServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.example.movies.domain.feature.client.service.ClientServiceImpl.<init>()
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1094)
    ... 40 more
Caused by: java.lang.NoSuchMethodException: com.example.movies.domain.feature.client.service.ClientServiceImpl.<init>()
    at java.lang.Class.getConstructor0(Class.java:2892)
    at java.lang.Class.getDeclaredConstructor(Class.java:2058)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
    ... 41 more
3
  • 1
    You are missing @Autowired ClientDAO otherwise add default constructor in ClientServiceImpl Commented May 26, 2015 at 18:55
  • Why is that? I want to inject it by constructor, and in the Bean method this is what i am doing. What i dont understand is why is not getting into that method, do you know the reason? Thanks for you answer Commented May 26, 2015 at 18:58
  • 1
    then annotate the constructor Commented May 26, 2015 at 19:02

1 Answer 1

2

You are trying to define ClientServiceImpl as a bean twice, once with @Bean method in config class, and once with @Service annotation in the class itself (the later will be picked up by component scanning triggered by @SpringBootApplication). So either add the @Autowired annotation as suggested by iamiddy to use @Service or remove the annotation and create in config class.

Sign up to request clarification or add additional context in comments.

4 Comments

Great! But why this does not happen when i run the service? Thanks for your answer!
And what do you think it would be more corret? Keep the @Service or keep the Bean method creation?
As to why the app works I can't say, maybe it works by "accident" due to different ordering, but I'm just guessing, can't really see an obvious reason for that.
As to which version to prefer, there is a difference between the two (at least in your case). IIRC the prototype scope means that you get a new instance of the service anytime it gets injected somewhere while the simple @Service annotation will create a singleton. If all you want is singletons and your @Bean annotated method contains no logic other than to knot together dependencies, I'd go with the @Service and let spring handle the dependencies for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.