如何在ASP.NET Web API中对自定义JsonConverter进行单元测试

本文关键字:自定义 JsonConverter 单元测试 API ASP NET Web | 更新日期: 2023-09-27 18:25:07

我有一个自定义JsonConverter,它从前端获取本地日期时间字符串,并使用NodaTime将其转换为DateTimeOffset

我替换了Json.NET.中的默认解析器

formatter.SerializerSettings = new JsonSerializerSettings
          {
              Formatting = Formatting.Indented,
              ContractResolver = new CustomResolver(),
              ReferenceLoopHandling = ReferenceLoopHandling.Ignore
          };

所以在我的测试中,我需要确保我配置了这个。

此时发生的情况是向我的API控制器发出POST请求。如果ViewModel(在API操作中使用)包含DateTimeOffset属性,则关联的JSON日期时间属性将通过转换器。

当转换器被触发时,应用程序首先获得User.Identity:

var user = (ClaimsIdentity) Thread.CurrentPrincipal.Identity;

成功后,我们提取Locality声明,其中包含IANA时区ID(例如"America/New_York")。

我们使用它将本地日期时间转换为相应的DateTimeOffset。

这就是我想要测试的。

我有JSON对象:

NameValueCollection nameValueCollection = new NameValueCollection() {
            {"dateCreated", "2015-11-30T14:22:00+1:00"},
            {"message", "Some message."},
            {"timelinePostId", "1"},
            {"applicationUser", ""},
            {"thumbs","" }
        };

但我被困在如何执行上

// Arrange
// Act
// Assert

我发现了这个MockHelper类,所以我已经准备好使用了。

public static HttpContextBase FakeHttpContext(HttpVerbs verbs, NameValueCollection nameValueCollection)
{
    var httpContext = new Mock<HttpContextBase>();
    var user = new ApplicationUser { 
            Id = "abc", 
            TimezoneId = "America/New_York" 
        };
    var request = new Mock<HttpRequestBase>();
    request.Setup(c => c.Form).Returns(nameValueCollection);
    request.Setup(c => c.QueryString).Returns(nameValueCollection);
    request.Setup(c => c.RequestType).Returns(verbs.ToString().ToUpper());
    var response = new Mock<HttpResponseBase>();
    var session = new Mock<HttpSessionStateBase>();
    var server = new Mock<HttpServerUtilityBase>();
    httpContext.Setup(c => c.Request).Returns(request.Object);
    var u = verbs.ToString().ToUpper();
    httpContext.Setup(c => c.Response).Returns(response.Object);
    httpContext.Setup(c => c.Server).Returns(server.Object);
    httpContext.Setup(c => c.User.Identity.GetUserId()).Returns("abc");
    httpContext.Setup(c => c.User.ApplicationUser()).Returns(user);
    return httpContext.Object;
}

所以我有我的JSON mock和Identity mock,但我如何让它工作呢?非常感谢您的帮助。

如何在ASP.NET Web API中对自定义JsonConverter进行单元测试

这里有一种不需要模拟整个HttpContext的方法。

在JsonConverter类中,将ReadJson中的逻辑重构为一个单独的方法,传入Identity对象:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    return DeserializeDate(reader, objectType, existingValue, serializer, (ClaimsIdentity)Thread.CurrentPrincipal.Identity);
}
public object DeserializeDate(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer, ClaimsIdentity identity)
{
    // do stuff...
}

然后根据DeserializeDate编写单元测试。