2012-07-24 67 views
2

我正在使用Mockito進行單元測試。我需要嘲笑填充一些輸入的無效方法。 非常非常簡單的例子:Mockito:在void方法中填充不同的值

class Something { 
    AnotherThing thing = new AnotherThing(); 
    public int doSomething(Stuff stuff) 
    { 
     thing.doThing(stuff); 
     if(thing.getName().equals("yes")){ 
     return 1; 
     } 
     else { 
     return 2; 
     } 
    } 
} 

class AnotherThing() { 
    public void doThing(Stuff stuff){ 
     if(stuff.getName().equals("Tom")) { 
      stuff.setName("yes"); 
     } 
     else { 
      stuff.setName("no"); 
     } 
    } 
} 

class Stuff() 
{ 
    String name; 
    // name getters and setters here 
} 

在這種情況下,我將試圖嘲弄AnotherThing測試Something

但是,我在我正在測試的類中多次調用此void方法。每次我打電話時,我都需要不同的「Answer」。我的意思是,我想調用無效方法在每次調用時做不同的事情。

我查看了API並找不到解決方案。這對Mockito來說甚至可能嗎?

+0

請添加一些示例代碼 – Kowser 2012-07-24 05:24:30

+0

哎呀,好主意 – Slamice 2012-07-24 05:34:30

+0

我不太明白「無效方法...填充一些輸入」的含義是什麼。 – 2012-07-24 05:40:10

回答

3

你需要的是一個Mockito Answer對象。這是一個包含一小部分功能的對象,您可以在調用模擬方法時運行該功能。查看doAnswer的Mockito文檔以獲取更多詳細信息;但基本上你想要的是這樣的。

doAnswer(new Answer<Object>(){ 
     @Override 
     public Object answer(InvocationOnMock invocation){ 
      Object[] arguments = invocation.getArguments(); 
      Stuff argument = (Stuff) arguments[0]; 
      if(stuff.getName().equals("Tom")) { 
       stuff.setName("yes"); 
      } 
      else { 
       stuff.setName("no"); 
      } 
      return null; 
     } 
    }).when(mockObject).doThing(any(Stuff.class)); 
+0

對於解決方案來說,答案是保持'void'返回類型。然而,這是非常冗長的代碼,所以如果可能的話,我傾向於重構受測試的類。 – Brad 2012-07-31 09:24:56

+0

@Brad是的,情況確實如此。我只是試圖用原始海報的原始代碼來說明答案。我認爲原來的代碼是出於說明的目的,並不是因爲這將出現在海報的完成軟件中。 – 2012-07-31 09:27:13

+0

+1導致它解決了這個問題,雖然我希望有一個更優雅的方式,就像這個方法不是無效的一樣,因爲mockito的文檔不鼓勵使用答案 – fd8s0 2013-04-24 15:21:40

2

Mockito爲您提供了連續呼叫存根的可能性。我認爲這是你需要的。這裏是mockito documentation中必要部分的鏈接。

你可以這樣寫:

Mockito.when(mockAnotherThing.doThing(stuff)).thenReturn("yes").thenReturn("no"); 

第一invocetion在此之後的Mockito將返回「是」,並在第二 - 「不」。

順便說一句,我認爲你需要改變你的示例代碼如下(在其他情況下,它不會工作):

class AnotherThing() { 
    public String doThing(Stuff stuff){ 
     if(stuff.getName().equals("Tom")) { 
     return "yes"; 
     } 
     else { 
      return "no"; 
     } 
    } 
} 
+0

啊,但我的問題是它是否有可能連續調用無效方法? – Slamice 2012-07-24 06:57:40

+0

好的。在這種情況下,請澄清你想要做什麼(可能是更好的例子)。因爲我不明白爲什麼你需要模擬無效方法,你想測試什麼。 – dimas 2012-07-24 07:06:30

0

不能使用等於作爲返回類型爲void要麼改變返回doThing()的類型爲String,然後嘲笑這樣

Anotherthing anotherthing = mock(Anotherthing.class) 
when(anotherThing.doThing(isA(Stuff.class))).thenReturn("yes").thenReturn("no"); 

你可能想這個多次否則最後一次掐滅值(「否」則返回)後,連續2個呼叫嘲笑;

0

爲什麼你需要不同Answer?你可以使用相同的一個:

doAnswer(new Answer<Object>(){ 
    private int call; 
    @Override 
    public Object answer(InvocationOnMock invocation){ 
     ... 
     call = call + 1; 
     if (call % 2 == 0) { 
     //do something 
     } else { 
     //another behavior 
     } 
    } 
}).when(mockObject).doThing(any(Stuff.class)); 
0

有一個simpler way

doNothing().doNothing().doThrow(new RuntimeException()).when(mock).someVoidMethod(); 

這樣的方法,多次調用可以做不同的事情。