2013-11-29 69 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將bean放置在實現UserService接口的jdk代理後面,之後該bean僅可用作UserService而不是DefaultUserService。 見https://stackoverflow.com/a/18875681/241986

您可以嘗試設置帶有屬性佔位符@Value("${someprop}")的表名,並在測試上下文中定義該屬性,或者創建另一個接口以暴露setTableName(),並將該助手接口自動裝入測試用例。

我不知道有這個問題的任何簡單的解決辦法,我覺得這個任務可以重新定義的bean的問題,在春季測試情境框架被包含 Spring beans redefinition in unit test environment

2

嘗試更換類DefaultUserService到接口UserService

public class UserServiceTest { 

    @Autowired 
    private UserService userService; 
    .... 

} 
+0

它的工作原理,但我不能調用'setTableName(...)'來設置我的測試表名稱,因爲'UserService'沒有這樣的方法聲明。 – Freewind

1

你有沒有在你的implementing class .Spring IOC容器定義的getter你的財產tableName工程對POJO模型