2017-08-26 31 views
-1

這不是Test class with a new() call in it with Mockito的重複。我試圖編寫一個測試來驗證某些方法在我的間諜對象(mockToyFacade)的構造函數中被調用。Mockito:構造函數中的間諜調用(Java)

被測試的類是ToyFactoryFacade。這個想法是客戶端與ToyFactoryFacade(包裝一個ToyFactory)進行交互以生成ToyFacade,它本身就是Toy對象的一個​​包裝。

我想用Mockito驗證什麼?

我想驗證addToyName(toyName)addCreationTime(creationTimestamp)正在呼籲ToyFacade。這兩個方法都在ToyFacade的構造函數中調用。

這是什麼問題?

當我試圖窺探ToyFacade,並驗證上述兩種方法都被調用時,我收到一個錯誤,它說「實際上,這個模擬與零交互。」當我單獨調用方法(即不通過構造函數)時,驗證檢查正確。 我不確定我做錯了什麼。

測試代碼

public class ToyFactoryFacadeTest { 
    private Toy mockToy; 
    private ToyFacade mockToyFacade; 
    // System under test. 
    private ToyFactoryFacade toyFactoryFacade; 
    private ToyFactory mockToyFactory; 
    @Before 
    public void setup() { 
     mockToy = mock(Toy.class); 
     mockToyFacade = spy(new ToyFacade(mockToy, "Phone", System.currentTimeMillis())); 
     mockToyFactory = mock(ToyFactory.class); 
     toyFactoryFacade = new ToyFactoryFacade(mockToyFactory) { 
      @Override 
      public Toy getToyFacade(String toyName, long creationTimestamp){ 
       return mockToyFacade; 
      } 
     }; 
    } 

    @Test 
    public void testToyFactoryFacade() { 
     toyFactoryFacade.initializeAndGetToy("Phone", System.currentTimeMillis()); 
     verify(mockToyFacade).addToyName("Phone"); 
     verify(mockToyFacade).addCreationTime(anyLong()); 
    } 
} 

源代碼

public class ToyFactoryFacade { 
    private final ToyFactory toyFactory; 
    public ToyFactoryFacade(ToyFactory toyFactory) { 
     this.toyFactory = toyFactory; 
    } 

    public ToyFacade initializeAndGetToy(String toyName, long creationTimestamp) 
    { 
     getToyFacade(toyName, creationTimestamp); 
    } 

    // For testing. 
    protected ToyFacade getToyFacade(String toyName, long creationTimestamp 
    { 
     return new ToyFacade(toyFactory.newToy(), toyName, creationTimestamp); 
    } 
} 

public class ToyFactory { 
    public Toy newToy() { 
    return new Toy(); 
    } 
} 

public class ToyFacade { 
    private final Toy toy; 
    public ToyFacade(Toy toy, String toyName, long creationTimeStamp) { 
     this.toy = toy; 
     addToyName(toyName); 
     addCreationTime(creationTimestamp); 
    } 

    public void addToyName(String name) { 
     toy.addToyName(toyName); 
    } 

    public void addCreationTime(long timestamp) { 
     toy.addCreationTime(timestamp); 
    } 
} 

public class Toy { 
    public String toyName; 
    public String creationTimestamp; 
    public void addToyName(String name) { 
     toyName = name; 
    } 

    public void addCreationTime(long timestamp) { 
     creationTimestamp = timestamp; 
    } 
} 
+0

這是**不是**重複的[https://stackoverflow.com/questions/45898462/mockito-spying-java-constructor-method-calls](Test類與新()調用它與的Mockito)。在這裏,我窺探一個類(ToyFacade),它在構造函數初始化時調用2個輔助方法。我的問題是爲什麼我無法驗證這兩種方法被調用。 Dawood的觀點是,我真的應該驗證這兩個調用對mockToy對象的影響,而不是驗證調用是在ToyFacade間諜(mockToyFacade)本身上進行的。 – Roberto

回答

0

您的測試沒有做你所期望的,因爲該方法調用你想驗證你創建之前已經發生你的間諜。你真正想做的是測試這兩個方法調用的效果,而不是調用本身。這看起來像

verify(mockToy).addToyName("Phone"); 
verify(mockToy).addCreationTime(timestamp); 

其中timestamp是無論你在setUp方法傳遞。

+0

感謝Dawood。正如你指出的那樣,我確實看到測試這些調用對後備玩具對象(mockToy)的影響如預期那樣工作。出於好奇,有沒有一種方法可以驗證mockToyFacade上的那些調用是否發生,除了對正在觀察的mockToy對象產生期望的影響? – Roberto

+0

不是我所知道的。如果有的話,你不應該使用它。因爲當你測試一個班級時,你應該驗證它對班級本身之外的影響。如果你發現自己在類內測試機制,你就會有代碼味道。 –

+0

有道理。謝謝! – Roberto