2015-12-21 60 views
1

我有一個AbstractDao類,我正在實例化Rest Fore API。我無法在Power Mock中模擬新的強制API(config)。請建議。模擬抽象類中的新對象實例

public abstract class AbstractDao { 

@Inject 
private Configuration configuration; 

public ForceApi getForceAPI() { 
    ApiConfig config = new ApiConfig(); 
    config.setClientId("test"); 
    config.setClientSecret("test"); 
    config.setUsername("test"); 
    config.setPassword("test"); 
    config.setLoginEndpoint("test"); 
    return new ForceApi(config); 
} 

} 

我想以這種方式做,但它不工作。 我DAO類擴展抽象DAO類

@RunWith(BlockJUnit4ClassRunner.class) 
public class SalesForceDaoImplTest { 

@InjectMocks 
private SalesForceDaoImpl salesForceDao; 
@Mock 
private ForceApi forceApiMock; 
@Mock 
private ApiConfig apiConfigMock; 
@Mock 
private Configuration configMock; 
@Mock 
JsonObject jsonobject; 


@Before 
public void setup() { 
    initMocks(this); 
    when(configMock.getAppConfiguration()).thenReturn(jsonobject); 
    when(jsonobject.getString(anyString())).thenReturn("test"); 
    when(salesForceDao.getForceAPI()).thenReturn(forceApiMock); 
    when(new ApiConfig()).thenReturn(apiConfigMock); 
    when(new ForceApi(apiConfigMock)).thenReturn(forceApiMock); 
} 
+0

是什麼意思,它不工作?你能更具體一點嗎? – Rufi

+0

你可以看看[這個問題](https://stackoverflow.com/questions/26320127/how-to-mock-objects-created-inside-method/26323140#26323140)。有一個如何用'PowerMockito'來模擬構造函數的例子 – troig

回答

0

也許這是一個遲到的答覆,但我相信它仍然可以給我們一些人,程序員有用。

免責聲明:我從來沒有與PowerMockito的工作,但我已經使用PowerMock不少 至於troig的建議: PowerMock驅動的單元測試假定你有一個專用亞軍運行:

@RunWith(PowerMockRunner.class) 

在這種情況下,與問題中陳述的@RunWith(BlockJUnit4ClassRunner.class)衝突,因此RunWith的「插槽」已被佔用。

這種特殊的一個仍然可以通過運行功率模擬作爲JUnit的規則的最新版本可以解決(我假設你運行JUnit)你可以找到這樣here 但是底線的一個例子,這是與權能問題之一嘲笑。

還有其他的問題,以及其基本上由我來的結論,即功率模擬應避免不應在新項目中使用(和電源的Mockito以及):

  • 單位功率模擬測試很慢(比EasyMock慢很多,如果它可以重寫使用)

  • Power Mock有時會測試字節碼與工具(如jacoco代碼覆蓋率)不兼容, t覆蓋類的單元測試與功率模擬或至少做錯了

  • 負責在maven中運行測試的Surefire插件具有並行運行多個單元測試的功能。有時用力量模擬它是不可能的。

  • 即使IntelliJ有時無法運行包含功耗模擬測試的套裝。

但最重要的事情是,當你不得不用這樣的功率模擬工具,可能是代碼可以(也應該)進行重構,更清潔,易於理解。關於你提到的具體的問題:

你違反類的編碼原則,指出該類不應該採取的本身依賴護理。這裏DAO實際上是「構建」並配置另一個(外部)服務供以後使用。

我建議你看MISKO Hevery about clean code的一個很好的演講,以更好地理解我的意思

如此反覆,在你的榜樣。它好得多保持ForceApi由依賴注入框架構建的依賴關係(我看到你已經在使用@Inject所以你在正確的軌道上)

在此實現請看:

public abstract class AbstractDao { 

    @Inject // this one is constructed and injected by your favorite DI framework in real use cases 
    private ForceApi forceApi; 

    public void doSomething() { 
     // do your dao stuff here 
     forceApi.callSomeAPIMethod(); 
     // do your dao stuff here 
    }  
} 

現在進行單元測試你不再需要功率模擬了。它足以根據情況使用簡單的模擬甚至是存根。所有你需要的是提供一個構造函數,它將採用ForceApi類型的參數,或者可能是一個setter(你可以考慮將它封裝爲私有的,這樣任何人都無法在測試之外調用它)。

我沒有足夠的信息來解決您的問題,但我提供的設計可能無需爲DAO提供一個Abstract類,這在某些情況下也可能有所幫助,因爲繼承有時可以是一個相當沉重的'義務'來維護(至少想想這個)。也許在這種情況下,繼承只是爲了支持這種行爲。在這種情況下,隨着項目的增長,可能有一些方法會被添加到AbstractDAO中,僅僅是因爲它方便這樣做,但是這些方法將「透明地」添加到所有DAO的整個層次結構中。這種結構變得脆弱,因爲如果至少有一種方法改變了它的實現,DAO的整個層次結構可能會失敗。

希望這會有幫助