2009-10-28 95 views
4

我在我的代碼中使用Spring註釋來執行DI。所以可以說我有一類class1依賴於其他類class2,我定義的Class1如下:模擬對象和Spring註釋

@Component 
public class class1 { 

@Resource 
private interface2 object2; 

} 

的Class2是接口2的實現。

現在讓我們說我想嘲笑class2並將它傳遞給class1,我沒有看到class1中的任何構造函數或setter。我認爲Spring使用反射來注入object2。我怎麼嘲笑它?我應該在class1中添加一個setter嗎?或者我可以像Spring一樣重複使用它 - 我的意思是spring本身有一個模擬對象框架或其他東西,我打算使用EasyMock進行模擬。

感謝

回答

6

在Spring中ReflectionTestUtils class可能會有所幫助。
好像你在找什麼......至少注射部件:-)

+2

它不是僅鏈接,@some。鏈接文本是他需要解決問題的類的名稱。如果剝離鏈接減價,您仍然有答案。這是試金石。請參閱:https://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-an-answer-not-an-answer –

0

據我所知,有內置彈簧不再帶着嘲弄的框架,所以你需要使用像EasyMock的。我在過去做到了這一點的方法是使用XML而不是註釋*

  • 爲主要應用的配置在appContext-main.xml定義和測試配置(模擬對象)是

    • 定義Spring配置在appContext-test.xml
    • 定義當應用程序只運行appContext-main.xml裝入appContext-test.xml有模擬bean必須有在appContext-main.xml
    • 相同的ID相應的bean
    • 當測試運行機器人h加載了appContext-main.xmlappContext-test.xml。確保他們在這個順序加載,這樣的嘲笑「覆蓋」同名

    的任何豆*您不必需要轉換所有 Spring配置到XML使用這種方法。只有具有模擬實現或注入了模擬實現的bean才需要進行更改。其他bean可以繼續使用註釋進行定義。

  • +0

    我想要爲各種測試(可以說模擬拋出異常或返回null等)有許多相同類的模擬,所以我不確定創建多個xmls並重寫它們是否合適。 – Arvind

    0

    通過反射注入自己很容易,所以你可以避免使用setter方法。

    自己做是這樣的:

    for (Field field : injectable.getClass().getDeclaredFields()) { 
         MyAnnotation annotation = field.getAnnotation(MyAnnotation.class); 
         if (annotation != null) { 
          field.setAccessible(true); 
          Object param = generateMockObject(); 
          field.set(injectable, param); 
         } 
        } 
    
    1

    ReflectionTestUtils是最容易添加你想要的模擬(我們使用jMock,但它其實並不重要),缺點它是脆弱的。如果您重命名該字段,則必須記得也要更改測試。

    您也可以使用此:http://i-proving.com/2006/11/09/using-jmock-and-inject-object/

    它描述瞭如何在Spring上下文中使用嘲笑的對象。

    3

    Mockito具有處理嘲笑和DI一個真正強大的方式:

    @RunWith(MockitoJUnitRunner.class) 
    public class Class1Test { 
        @Mock 
        private Interface2 inteface2mock; 
    
        @InjectMocks 
        private Class1 class1; 
    
        @Test 
        public void someTest() { 
         when(interface2mock.doSomething("arg")).thenReturn("result"); 
    
         String actual = class1.doSomeThatDelegatesToInterface2(); 
    
         assertEquals("result", actual); 
        } 
    } 
    

    中的javadoc的Mockito或在blog post我前段時間寫的話題了解更多關於@InjectMocks

    自Mockito 1.8.3起可用,在1.9.0中增強。

    0

    有一個JUnit規則,以Mockito的方式爲EasyMock提供類似註釋驅動的注入功能。請參閱EasyMockRule