2017-02-21 30 views
1

當其他類調用方法「ProductAdapterService.adapt」時,我想模擬「源代碼」。如何用PowerMockito模擬一個局部變量?

如何處理?我真的嘗試了很多方法。請幫幫我。我是一個新人。非常感謝!

public class ProductAdapterService { 
private final SearchParameter parameter; 
private List<Festival> festivals; 

public ProductAdapterService(SearchParameter parameter) { 
    this.parameter = parameter; 
} 

public SingleProduct adapt(SearchHit hit, boolean bidding) { 

    //I want to mock "source", I don't want to use "hit.getSource()" 
    Map<String, Object> source = hit.getSource(); 

    SingleProduct sp = new SingleProduct(); 
    sp.setId(TypeConverter.toInt(source.get(FieldName.PRODUCT_ID))); 
    sp.setName(TypeConverter.toString(source.get(FieldName.NAME))); 
    sp.setPrice(this.price(source.get(FieldName.PRICE), source.get(FieldName.PRICE_MAP), source.get(FieldName.FIRST_START_CITIES))); 
    sp.setLevel(TypeConverter.toInt(source.get(FieldName.PRODUCT_LEVEL))); 
    sp.setDepartureCityId(this.departureCity(source.get(FieldName.DEPARTURE_CITY_ID), source.get(FieldName.FIRST_START_CITIES))); 
    sp.setSaleMode(TypeConverter.toString(source.get(FieldName.SALE_MODE))); 
    sp.setBrandName(this.providerBrandName(source.get(FieldName.PROVIDER_BRAND))); 
    sp.setSaleCount(TypeConverter.toInt(source.get(FieldName.MONTHLY_ORDER))); 
    sp.setCommentCount(TypeConverter.toInt(source.get(FieldName.COMMENT_COUNT))); 
    sp.setCommentScore(TypeConverter.toFloat(source.get(FieldName.COMMENT_SCORE))); 
    sp.setBuType(BuType.GT); 
    sp.setType(this.productType(source.get(FieldName.SEARCH_TAB_TYPE_SHOW), sp.getSaleMode())); 
    sp.setSaleout(this.saleout(source.get(FieldName.NON_SALEOUT_CITIES), sp.getDepartureCityId())); 
    if (!sp.isSaleout()) { 
     sp.setFestival(this.festival(source.get(FieldName.FESTIVAL_IDS))); 
    } 
    System.out.println("sp.getName(): " + sp.getName()); 
    return sp; 
}} 

而下面是我的測試代碼:

public class TabSearcherTest0 { 

@Test 
public void test() { 
    SearchParameter parameter = SearchParameter.create(); 
    Ghost.begin(); 
    parameter.getFiltered().setTab(TabType.ALL); 
    parameter.getPoi().setKeyword("Spa"); 
    parameter.getClient().setTrace(TraceMode.MAIN); 

    Map<String, Object> mapMock = new HashMap<String, Object>(); 
    mapMock.put("productgroupid", "12877"); 
    mapMock.put("productid", "5539739"); 
    mapMock.put("firststartcitys", "[1, 2]"); 
    mapMock.put("nonsaleoutcities", "[1, 2]"); 
    mapMock.put("productdiamondlevel", "4"); 
    mapMock.put("commentcount", "0"); 
    mapMock.put("price", "0.0"); 
    mapMock.put("name", "TestName"); 
    mapMock.put("searchtabtypeshow", "1"); 
    mapMock.put("comment", "0.0"); 
    mapMock.put("salemode", "S"); 
    mapMock.put("providerbrandid", "999999"); 
    mapMock.put("departurecityid", "2"); 

    // how to inject the map? 
    // ??? 

    SearchModel model = SearchContext.createContext(parameter).search(); 
    Ghost.end(); 
    System.out.println(model); 

}} 
+0

你的測試代碼在哪裏?你想要測試什麼? – DamCx

+0

在'SearchHit'上模擬'getSource()'方法。我看不到你用'hit'來做其他事情。或者直接注入地圖,而不是'SearchHit'。 –

+0

我加了測試代碼,請幫我 – mike

回答

0

你得到 「嘲諷」 走錯了路。你只有使用它的時候你不能使用使用真正的類實現;但是您需要控制某些對象如何響應調用方法。

你要測試的方法是這樣的:

public SingleProduct adapt(SearchHit hit, boolean bidding) { 
    //I want to mock "source", I don't want to use "hit.getSource()" 
    Map<String, Object> source = hit.getSource(); 

錯誤:你確保hit.getSource()使用。因爲你的代碼生產正在使用的是;並且你編寫你的單元測試到文本那個代碼。所以你希望你的生產代碼能做到「正常」的事情。

所以,很乾脆的解決方案在這裏:

@Test 
public void testAdapt() { 
    SearchHit mockedHit = mock(SearchHit.class); 

    Map<String, Object> resonseForGetSource = new HashMap<>(); 
    resonseForGetSource.put("productgroupid", "12877"); 
    ... 

    doReturn(resonseForGetSource).when(mockedHit.getSource()); 

    ProductAdapterService underTest = ... 
    underTest.adapt(mockedHit, true); 
    ... probably some asserts 

或相似的東西(不要釘箱上doReturn /時的細節在這裏)

什麼,你可以在這裏看到:你的產品代碼需要地圖來完成其工作;所以你只需確保這樣一個地圖對象出現在你的生產代碼中。

並且萬一可以使用real SearchHit對象(您可以使用這樣的地圖進行配置);那麼使用它甚至會比嘲笑該對象更好。

您絕對嘗試最小化您對嘲笑的使用。您只能用它來控制某個測試過程中使用的對象。

除此之外:你不清楚你的單元測試的範圍。爲了測試那一種方法,你不需要沒有鬼。您所展示的單元測試代碼在您向我們展示的課程背景中根本沒有意義!因此:你最好後退一步,仔細研究「我擁有哪些單位」和「如何單位測試該單位X」。您不通過測試「Y」來輸入「X」!

+0

謝謝GhostCat。我明白你說的那句話後,我調整了我的方式,我錯了。 – mike

相關問題