2017-09-15 414 views
2

我想編寫一個單元測試來測試JsonProcessingException。這個異常可能發生在mapper.writeValueAsString()。JsonProcessingException的單元測試

public void myMethod(Args...) { 
     try { 
       ObjectMapper mapper = new ObjectMapper(); 
       mapper.configure(SerializationFeature.INDENT_OUTPUT, true); 

       Document.parse(mapper.writeValueAsString(testObject))); 
      } 
     } catch (JsonProcessingException e) { 
      log.error("Error parsing the object to json string. ", e); 
     } 
} 

,這裏是我的單元測試:

public class Test { 

    @Mock 
    private ObjectMapper    mapper; 

    @InjectMocks 
    ClassUnderTest   sut; 

    @Test 
    public void testJsonProcessingException() throws  JsonProcessingException { 
     when(mapper.writeValueAsString(Mockito.any())).thenThrow(new  JsonProcessingException("Error parsing the object to json string. "){ 
      private static final long serialVersionUID = 1L;}); 
     sut.myMethod(args...); 
    } 

} 

的問題是,我有嘲笑不會被用來映射器(我得到不必要的Mockito stubbings失敗)作爲映射器內再次初始化方法。我怎樣才能用mockito來測試這種情況?

回答

2

mapper不是被測實例的字段/依賴項。
這是法中創建一個局部變量:

public void myMethod() { 
     try { 
      ObjectMapper mapper = new ObjectMapper(); 
     ... 
} 

所以,@InjectMocks將是無奈。

我可以建議你兩種選擇:

1)你可以通過mapper作爲參數,通過改變方法的簽名:

public void myMethod(ObjectMapper mapper) { 
    ... 
} 

通過這種方式,你可以通過嘲笑ObjectMapper爲測試方法的論點。

如果經常調用此方法,傳遞一個鍋爐板參數可能會很煩人,並且使代碼不易讀。

2)另一種方法是提供一種方法來設置ObjectMapper通過被測試的類的構造函數。

public class ClassUnderTest{ 

    private ObjectMapper objectMapper; 
    ... 
    public ClassUnderTest(ObjectMapper objectMapper){ 
     this.objectMapper = objectMapper; 
    } 
    ... 
} 
+0

是的,的確如此。然而,我想找到一個解決方案,而不需要改變這個看起來不可能的課程。 –

+2

嘲笑,這確實是不可能的。但作爲選擇,你可以在不嘲笑ObjectMapper的情況下測試這個類。你應該僅僅傳遞測試方法的參數,這會拋出異常。 – davidxxx

+1

那麼,'新的ObjectMapper()'*可以很容易被嘲弄,但你說得對,測試不應該嘲笑任何東西。事實上,通過傳遞一個沒有註冊序列化器的'testObject',應該很容易使'mapper.writeValueAsString(testObject)'調用拋出異常。在這裏使用嘲諷只會導致與SUT的實施密切相關的糟糕測試。 –