2017-10-19 91 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,但仍然是相同的错误。 反过来想一个更好的方向,会更多地玩这个想法。感谢你目前的帮助! –