Pregunta

I'd like to test some services that them themself contain other autowired services. But these "external" services are not required for the test itself.

How can I create a test setup, eg for the following example?

package de.myapp.service;

@Service
public class MyServiceDelegator {
    @Autowired
    private List<ServiceInterface> services;

    public ServiceInterface delegate(String id) {
        //routine to find the right ServiceInterface based on the given id
    }
}


@Service
public class MyService implements ServiceInterface {

}

@Service
public class MyCustomService implements ServiceInterface {
    //that is the problem during testing
    @Autowired
    private de.myapp.repository.SomeDao dao;
}


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext.xml")
public class ServiceDelegatorTest {
    @Autowired
    private ApplicationContext ac

    @Test
    public void testDelegator() {
        MyServiceDelegator dg = ac.getBean(MyServiceDelegator.class);
        ac.delegate("test");
    }
}

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan  base-package="de.myapp.service" />
</beans>

Problem: All services that contain autowired dependencies from packages that are not scanned within the JUnit test (like MyCustomService), will throw an Exception:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [SomeDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) ... 57 more

¿Fue útil?

Solución

You can use Springockito to add mocked service implementations to your test application context.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mockito="http://www.mockito.org/spring/mockito"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans.xsd
                       http://www.springframework.org/schema/context
                       http://www.springframework.org/schema/context/spring-context.xsd"
                       http://www.mockito.org/spring/mockito
                       http://www.mockito.org/spring/mockito.xsd">

    <context:component-scan  base-package="de.myapp.service" />

    <mockito:mock id="dao" class="de.myapp.repository.SomeDao" />

</beans>

Otros consejos

The problem is that SomeDao is not being picked up by component scanning because it's not under the de.myapp.service package.

You have explicitly stated that the package for component scanning is de.myapp.service.

I sugggest you make the following change:

<context:component-scan base-package="de.myapp" />

That way all the code under de.myapp will be eligible for component scanning.

If you want to avoid including all your code in component scanning you could do the following:

<context:component-scan base-package="de.myapp.service, de.myapp.repository" /> 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top