2014-02-07 26 views
0

注:我故意刪除的話,從類和對象的名稱,因此,請在我的代碼示例藉口可怕的名字春天配置模擬給兩個不同的實例

我有一個測試類,設置使用一些測試Spring上下文文件來啓動應用程序。該應用程序是一個Web服務的包裝。

由於這是一項測試,我嘲笑了相關Web服務(ITransporter類)的主界面。這使我能夠設置期望值,以便我可以檢查發送到Web服務的請求是:以預期的格式;有預期的領域完成;等等......

我的模擬是在一個名爲test-beans-context.xml並傳遞到一些服務豆類文件中定義如下:

<bean id="mockTransporter" class="org.easymock.EasyMock" factory-method="createMock" scope="singleton"> 
    <constructor-arg index="0" value="transport.ITransporter" /> 
</bean> 
<bean id="accountService" class="service.AccountService"> 
    <property name="transporter" ref="mockTransporter" /> 
</bean> 

此背景下文件在2個地方使用。 (我擔心這是我的問題出現了。)

第一個是測試類,其被定義如下:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:test-beans-context.xml"}) 
public class AbstractIntegrationTest { 

    @Autowired 
    private ITransporter mockTransporter; 

    //Some tests that perform expectations like the following: 
    // EasyMock.reset(this.mockTransporter); 
    // EasyMock.expect(this.mockTransporter.sendRequest(EasyMock.capture(this.requestXmlCapture))).andReturn(responseXml); 
} 

第二位置是在一類是內的邏輯用於發送請求的路徑。它加載一個單獨的XML上下文文件/lite-api-context.xml,然後在我的測試設置中導入測試。

public class Factory implements IFactory { 
    public Factory() { 
     context = new ClassPathXmlApplicationContext("/lite-api-context.xml"); 
    } 
    @Override 
    public IAccountService getAccountService() { 
     return (IAccountService) context.getBean("accountService"); 
    } 
} 

而且lite-api-context.xml包括這樣的:

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

我的問題是,在測試類,我得到了嘲笑ITransporter的不同實例與在最終使用由我的其他一服務。所以我設定的期望從未實際執行,因爲模擬結果是不同的實例。

有沒有辦法確保我在兩個地方都得到相同的實例?

或者我將不得不創建我自己的ITransporter接口的單例測試實現? (基本上創造行爲完全像我現在的模擬做一個短線。)

編輯:(答案)

爲託姆說,看來我需要創建自己的類來管理模擬。

我想在這裏添加我的解決方案,以防萬一有人遇到類似的問題。

只是寫了一個快速靜態類是這樣的:

public class MockTransporter { 

    private static ITransporter mockTransporter = EasyMock.createMock(ITransporter.class); 

    public static final ITransporter getInstance() { 
     return mockTransporter; 
    } 
} 

,不得不XML配置改成這樣:

<bean id="mockTransporter" class="MockTransporter" factory-method="getInstance" /> 

回答

1

噢,這是一個問題。當你創建一個新的上下文就像爲Spring創建一個新的對象空間一樣。在您的XML文件中創建的與在手工製作的環境中創建的不同。他們會一直產生不同的變數。

我之前就被燒過了。

你只希望如果你想要相同的是管理自己的單身人士。

+0

感謝您確認我的恐懼。這樣的單身管理班的實施不應該太難,我只是希望我不需要一個。 –

+0

@DanTemple對不起,壞消息的持有者。如果你願意接受我的回答,我將不勝感激。 – Thom

1

解決此問題的理想方法是將Factory作爲Spring bean創建,並將AccountService注入到Factory bean中。 在生產代碼中應避免使用context.getBean(),因爲它會損害控制反轉的概念(有關更多信息,請參閱:Why is Spring's ApplicationContext.getBean considered bad?)。儘管如此,在測試代碼中使用它仍然可以。

+0

我完全同意。可悲的是,由於這個特定的Factory類是如何根深蒂固的,現在我不確定這種改變是可能的。 (這不僅僅是我的應用程序使用它)我總是可以創建一個新的樣式工廠,並使其可以配置爲Spring,但隨後會變得混亂和可能混亂。 –