2013-08-27 24 views
3

使用案例:doAnswer()來修改傳遞的對象沒有被要求虛空方法

我想打電話給使用對象的名單嘲笑類的方法,並希望修改傳遞的參數。它工作正常,如果我工作的返回類型的一些方法,並不適用於Void返回方法。

方法測試:

public class TestClass{ 
        @Autowired 

       PersistActivity activity; 

       public void methodToTest(List<URLObject> urlObjects) { 
          List<URLObject> urlObjects2PerformAction = new ArrayList<URLObject>(); 

        for (URLObject urlObject : urlObjects) { 
          // Added this check to make sure, we are not running a previous 
          // activity which is successful. 
          if (urlObject.getRetryCountMap().get(currentActivityName) != null) { 
            urlObjects2PerformAction.add(urlObject); 
          } 
        } 
        boolean activityStatus = true; 
        try { 
         log.info("Calling activity " + currentActivityName + " with " + urlObjects2PerformAction); 
         activity.doActivity(urlObjects2PerformAction); 
         log.info("UrlObjects are " + urlObjects2PerformAction); 
        } catch (Exception e) { 
         //another set of actions. 
        } 
        for (URLObject urlObject : urlObjects) { 
         if (!urlObject.isActivitySuccessful()) { 
           // If complete call failed or partial data failed, update 
           log.info("Failed for message " + urlObject); 
         } else { 
          log.info("Passed for message " + urlObject); 
         } 
        }//end for 
      }//end method 
     }//end class  

在這個例子中,我想修改urlObjects來填充它的布爾變量之一是真/假。

我已經在測試情況下加入一個doAnswer()子句是這樣的:

測試類:

public class TestMe{ 
    @Mock 
    private PersistActivity activity; 

    @Captor 
    private ArgumentCaptor<List<URLObject>> argument; 

    @InjectMocks 
    private DCUrlPersistor dcUrlPersisor = new DCUrlPersistor(); 


    @Test 
public void runIndividualDeamonWithMultipleMessagesSomeFailing() throws Exception { 


    URLObject urlObject1 = getUrlObject(normalizedUrl, normalizedUrl, scraperName); 
    URLObject urlObject2 = getUrlObject("test2.com", "test2.com", "gpsUS"); 


Map<String,Integer> retryCountMap = new HashMap<String, Integer>(); 
retryCountMap.put(PersisterActivitiesEnum.CSI.getName(), 0); 

urlObject1.setRetryCountMap(retryCountMap); 
urlObject2.setRetryCountMap(retryCountMap); 

/** 
* Change argument passed to the method. 
*/  
doAnswer(new Answer<Object>() { 

    @Override 
    public Object answer(InvocationOnMock invocation) 
     throws Throwable 
    { 
     Object[] arguments = invocation.getArguments(); 

     if ( arguments != null 
       && 
       arguments.length > 0 
       && 
       arguments[0] != null) 
     { 
      List<URLObject> objs = (List<URLObject>) arguments[0]; 
      Assert.assertNotNull(objs.get(0).getRetryCountMap()); 
      objs.get(0).setActivitySuccessful(false); 
     } 
     return null; 
    }  
}).when(activity).doActivity(anyList()); 


doNothing().when(activity).doActivity(Arrays.asList(urlObject1, urlObject2)); 

/** 
* Call method. 
*/ 
dcUrlPersisor.methodToTest(Arrays.asList(urlObject1, urlObject2)); 
/** 
* Verify various instances and logs. 
*/ 
verify(activity, times(1)).doActivity(argument.capture()); 
assertEquals(2, argument.getValue().size()); 
assertEquals(normalizedUrl, argument.getValue().get(0).getNormalizedURL());  
Assert.assertTrue(logContains("Calling activity csi with ")); 
//-----This is the part which fails as log never prints this message----// 
Assert.assertTrue(logContains("Failed for message")); 


    } 
} 

問題:

如果更改doActivity方法的返回類型爲List<ABC>Void ,那麼它會被調用並按預期工作(不會更改測試代碼)。

我們是否需要對void方法進行一些更改?我已經將它設置爲在doAnswer中返回void。

任何幫助,將不勝感激。

+0

「Activity」看起來像什麼?你有沒有得到任何錯誤?另外,你的代碼有幾個編譯錯誤和運行時錯誤 - 除非你打算用'ABC'到處替換'URLObject'?無論如何,你可以發佈你的實際代碼嗎?謝謝。 – Jonathan

+0

如果我更正了編譯問題,並用'ABC'代替'URLObject'並假設'Activity'具有'void doActivity(列表 abcs)'方法,它適用於我,即'abc [0] .activitySuccessful == false' 。也許其他事情正在發生? – Jonathan

+0

@Jonathan感謝您的時間。我可能會做一些愚蠢的事情,並添加了最少量的代碼來理解流程。 – instanceOfObject

回答

1

嘗試刪除以下行:

doNothing().when(activity).doActivity(Arrays.asList(urlObject1, urlObject2)); 

對我來說,這似乎有點違背設立doAnswer它前面。

+0

糟糕! :(我認爲這是一個複製粘貼,我不知道有兩個動作定義! – instanceOfObject

0

Void更改爲Object這樣。

... 
doAnswer(new Answer<Object>() { 
    @Override 
    public Object answer(InvocationOnMock invocation) throws Throwable { 
    ... 
+0

嗨大衛,爲什麼它應該工作?返回類型的方法是無效的。你希望返回修改後的對象嗎? 雖然我試過了,但沒有奏效。 – instanceOfObject

+0

我將Answer的返回類型更改爲Object,並且返回null。 – instanceOfObject

+1

好的,也許你的模擬對象實際上並沒有按照你的想法注入。你可以發佈你的實際測試類,所以我們可以找到錯誤?它看起來像你試圖重新輸入它,並做了一些拼寫錯誤(如InjectMocks的拼寫),所以很難確定發生了什麼。 –

相關問題