2017-02-21 443 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