2013-11-29 6 views
4

Я создал интерфейс и класс:Почему весна не может найти мою фасоль?

public interface UserService { 
    List<User> listAll(); 
} 

@Transactional 
public class DefaultUserService implements UserService { 
    private String tableName; 
    public List<User> listAll() { someDao.listAllFromTable(tableName); } 
    public void setTableName(String tableName) { this.tableName = tableName; } 
} 

Кроме того, в моем контекстном XML файла context.xml, я определил:

<bean id="userService" class="mypackage.DefaultUserService"> 
    <property name="tableName" value="myusers" /> 
</bean> 

Тогда я хочу, чтобы проверить DefaultUserService:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:context-test.xml"}) 
@TransactionConfiguration(transactionManager = "testTransactionManager") 
@Transactional 
public class UserServiceTest { 

    @Autowired 
    private DefaultUserService userService; 

    @Before 
    public void setup() { 
     userService.setTableName("mytesttable"); 
    } 
    @Test 
    public void test() { 
     // test with userService; 
     userService.listAll(); 
    } 
} 

Обратите внимание, что он использует context-test.xml, который импортировал оригинал context.xml:

<import resource="classpath:context.xml"/> 

К сожалению, когда начинается тест, весна бросает исключение:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'mypackage.UserServiceTest': 
Injection of autowired dependencies failed; 
nested exception is org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: 
private mypackage.DefaultUserService mypackage.userService 

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [mypackage.DefaultUserService] 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)} 

Я не уверен, где это неправильно, почему весна не может найти компонент DefaultUserService я определил?

+0

Параметра '' декларации у вас есть в 'context-test.xml'? –

+0

Вы имели в виду 'public class DefaultUserService' в этом первом кодеблоке? – Dan

+0

@Sotirios, см. Мой обновленный вопрос, у меня есть эта декларация. – Freewind

ответ

2

Это потому, что @Transactional указывает, что компонент находится за прокси-сервером jdk, реализующим интерфейс UserService, после чего компонент доступен только как UserService, а не DefaultUserService. См. https://stackoverflow.com/a/18875681/241986.

Вы можете попробовать установить имя таблицы с помощью заполнителя свойств @Value("${someprop}") и определить это свойство в тестовом контексте или создать другой интерфейс, который будет выставлять setTableName(), и автоустанавливать этот вспомогательный интерфейс в тестовый пример.

Я не уверен, есть ли простые решения этой проблемы, я думаю, что эта задача может быть отнесена к проблеме боба переопределения в Spring тест-контексте рамках Spring beans redefinition in unit test environment

2

Попробуйте заменить класс DefaultUserService к интерфейсу UserService

public class UserServiceTest { 

    @Autowired 
    private UserService userService; 
    .... 

} 
+0

Он работает, но я не могу назвать 'setTableName (...) ', чтобы установить имя моей тестовой таблицы, так как 'UserService' не имеет такого объявления метода. – Freewind

1

Вы не определили getter для вашего имущества tableName в вашем implementing class .Spring IOC контейнер работает на POJO модели

Смежные вопросы