2014-03-19 71 views
3

我寫在彈簧項目TestNG的測試案例和使用jmockit來模擬依賴。我遇到一個問題,就是我不能使用Deencapsulation.setField設置依賴於Spring管理對象包含一個@Transactional方法,錯誤的是:如何注入由jmockit嘲笑對象與方法@Transactional彈簧管理對象?

類爪哇發現的名字「dataLogManager」的任何實例字段.lang.reflect.Proxy

這裏列出我的示例代碼,

測試用例:

public class QueueManagerTest extends AbstractTestNGSpringContextTests { 
    @Autowired 
    private QueueManager queueManager; 

    @Autowired 
    private ApplicationContext context; 

    @Autowired 
    private TransInfoManager transInfoManager; 

    @Autowired 
    private Generator generator; 

    @Autowired 
    private MessageDTOFactoryBean messageDTOFactoryBean; 

    @Test(description="單元測試:寫入一筆Data資料,非邊界情況下(無待處理筆數)") 
    public void writeControlMessage(   
     @Mocked final TransInfoManager transInfoManager, 
     @Mocked final DataManager dataManager, 
     @Mocked final DataLogManager dataLogManager 
     ) { 
    .... 
     Deencapsulation.setField(queueManager, "dataLogManager", dataLogManager); 
     Deencapsulation.setField(queueManager, "dataManager", dataManager); 
     Deencapsulation.setField(queueManager, "transInfoManager", transInfoManager); 
    .... 
    } 
} 

服務:

@Service 
public interface QueueManager {   

    @Transactional 
    MessageDTO putDataIntoQueue(MessageDTO message); 

} 

任何人都知道如何解決這個問題?謝謝。

回答

1

如果你想測試的是一些實現QueueManager接口的特定類,那麼解決方案就是直接在測試中實例化類,而不是使用Spring來實現。

的原因除了是Spring實際上創建了queueManager領域代理類實例,旨在裝點真正落實(代理對象代表每一個方法調用另一個對象,這將是一個實例應用程序類實際上實現了接口QueueManager)。代理類不包含一個名爲「dataLogManager」字段,所以這就是爲什麼Deencapsulation.setField(...)無法找到它。

如果我提到的第一個解決方案是不適用的,你仍然可以讓Spring做實例,只要它也注入queueManager對象中的字段。嘲笑類實施DataLogManager(和其他接口),使用@Capturing代替(或除了)@Mocked;這將指示JMockit擴展到所有實現類的模擬。