2017-10-19 133 views
3

寫了一個自定義JsonConverter來處理不同版本的相同api返回的不同Json格式。一個應用程序向其他幾個應用程序發出請求,我們不知道將返回哪種格式,因此JsonConverter處理此問題並似乎運行良好。我需要爲項目添加單元測試,除了我沒有找到有用的資源來幫助模擬一些Newtonsoft.Json對象,主要是JsonReader。如何模擬JsonReader單元測試自定義JsonConverter

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject jsonValue = JObject.Load(reader); 
     if(jsonValue == null) 
     { 
      return null; 
     } 

     var responseData = ReadJsonObject(jsonValue); 
     return responseData; 
    } 

    [TestMethod] 
    public void ReadJsonReturnNullForNullJson() 
    { 
     var converter = new DataConverter(); 

     _mockJsonReader.Setup(x => x.Value).Returns(null); 

     var responseData = converter.ReadJson(_mockJsonReader.Object, typeof(ProbeResponseData), null, _mockJsonSerializer.Object); 

     Assert.IsNull(responseData); 
    } 

一些代碼已經從ReadJson方法中取出。我想安裝JsonReader返回實際JSON的值,在這種情況下是空值,但在其他單元測試中,我想要一個實際的Json(JObject)。在運行單元測試時,我收到一個「Newtonsoft.JsonReaderException:從JsonReader讀取JObject時出錯。路徑''。」

+0

看看在測試中使用SerializeObject/DeserializeObject與已知類型進行接觸;並讓我知道如果我錯過了一些東西,所以我可以提供一個完整的答案。 –

+0

@JeffDalley using JsonConvert.DeserializeObject (jsonString);調用自定義轉換器的ReadJson方法,而不需要模擬一些NewtonSoft框架工作。這種方法完全有效!隨時發佈您的答案。 –

回答

2

使用DeserializeObject<T>將在您的引擎下調用您對ReadJson的覆蓋。

[TestMethod] 
public void ReadJsonVerifyTypeReturned() 
{ 
    var testJson = CreateJsonString(); 

    var result = JsonConvert.DeserializeObject<ProbeResponseData>(testJson); 
    var resultCheck = result as ProbeResponseData; 

    Assert.IsNotNull(resultCheck); 
} 
+0

感謝您的幫助! –

0

不知道你的自定義轉換器的內部工作原理,你可以創建一個測試double而不是模擬嗎?

public class JsonReaderThatReturnsNull : JsonReader 
{ 
    public override bool Read() 
    { 
     return true; 
    } 

    public override object Value => null; 
} 
+0

所以我喜歡這種方式,從來沒有想過這樣做。然而,當我這樣做,測試從未停止運行。它似乎繼續調用Read()直到它爲false。試圖添加一個標誌,所以它只能讀取一次,但我收到以前一樣的錯誤,從來沒有得到的價值。試圖返回一個實際的json,以防萬一讀者本身不會返回null,但仍然是相同的錯誤。 反過來想一個更好的方向,會更多地玩這個想法。感謝你目前的幫助! –