从HttpResponseMessage获取内容以使用c#动态关键字进行测试

时间:2013-02-05 15:30:16

标签: c# unit-testing asp.net-web-api

在其中一个动作中,我做了类似的事情

public HttpResponseMessage Post([FromBody] Foo foo)
{
    .....
    .....

    var response = 
          Request.CreateResponse(HttpStatusCode.Accepted, new { Token = "SOME_STRING_TOKEN"});
    return response;
}

以及更多像这样返回匿名类型实例的方法,它运行良好。

现在,我正在为它编写测试。我有

HttpResponseMessage response = _myController.Post(dummyFoo);

HttpResponseMessage有一个名为Content的属性,并且有一个ReadAsAsync<T>()

我知道如果有具体的特定类型,我可以做

Bar bar = response.Content.ReadAsAsync<Bar>();

但是如何访问正在返回的匿名类型?有可能吗?

我希望做到以下几点:

dynamic responseContent = response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;

但是我得到的错误是object类型的实例没有属性Token。即使调试器显示带有一个属性Token的responseContent,也会发生这种情况。我理解为什么会这样,但我想知道是否有办法访问该物业。

enter image description here

由于

2 个答案:

答案 0 :(得分:12)

.ReadAsAsync<T>是一个异步方法,这意味着它不返回整个反序列化对象,而是返回Task<T>来处理整个异步任务的继续。

您有两种选择:

1。异步模式。

在封闭方法中使用async关键字(例如:public async void A())并以这种方式进行异步调用:

dynamic responseContent = await response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;

2。常规任务API

或者只使用Task API:

response.Content.ReadAsAsync<object>().ContinueWith(task => {
   // The Task.Result property holds the whole deserialized object
   string returnedToken = ((dynamic)task.Result).Token;
});

这取决于你!

更新

在您发布整个屏幕截图之前,没有人知道您正在调用task.Wait以等待异步结果。但我会保留我的答案,因为它可能会帮助更多的访客:)

正如我在对自己答案的评论中建议的那样,您应该尝试反序列化为ExpandoObject。 ASP.NET WebAPI使用JSON.NET作为其底层JSON序列化程序。也就是说,它可以处理对expando对象的匿名JavaScript对象反序列化。

答案 1 :(得分:0)

您还可以使用类似的以下代码通过单元测试来测试HttpResponseMessage。

这对我有用。

希望这对您有帮助

[TestClass]
    public class UnitTest
    {
        [TestMethod]
        public void Post_Test()
        {
           //Arrange
           var contoller = new PostController();  //the contoller which you want to test
           controller.Request = new HttpRequestMessage();
           controller.Configuration = new HttpConfiguration();

           // Act
           var response = controller.Post(new Number { PhNumber = 9866190822 });
           // Number is the Model name and PhNumber is the Model Property for which you want to write the unit test

           //Assert
           var request = response.StatusCode;
           Assert.AreEqual("Accepted", request.ToString());

        }
    }

类似地,根据需要在Assert中更改HttpResponseMessage。