使用 c# 动态关键字从 HttpResponseMessage 获取内容以进行测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14711038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting content from HttpResponseMessage for testing using c# dynamic keyword
提问by Professor Chaos
In one of the actions, I do something like this
在其中一项行动中,我做这样的事情
public HttpResponseMessage Post([FromBody] Foo foo)
{
.....
.....
var response =
Request.CreateResponse(HttpStatusCode.Accepted, new { Token = "SOME_STRING_TOKEN"});
return response;
}
and more methods like that return an anonymous type instance and it works well.
和更多类似的方法返回一个匿名类型实例,它运行良好。
Now, I'm writing tests for it. I have
现在,我正在为它编写测试。我有
HttpResponseMessage response = _myController.Post(dummyFoo);
HttpResponseMessage
has a property called Content
and has a ReadAsAsync<T>()
.
HttpResponseMessage
有一个名为的属性,Content
并且有一个ReadAsAsync<T>()
.
I know that if there was a concrete specific type, I can do
我知道如果有一个具体的特定类型,我可以做
Bar bar = response.Content.ReadAsAsync<Bar>();
but how do I access the anonymous type that's being returned? Is it possible?
但是如何访问返回的匿名类型?是否可以?
I was hoping to do the following:
我希望做到以下几点:
dynamic responseContent = response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;
but I got the error that instance of type object does not have the property Token. This happens even though the debugger shows responseContent with one property Token. I understand why that's happening, but I want to know if there is a way to access the Property.
但我收到错误,即类型对象的实例没有属性 Token。即使调试器显示具有一个属性令牌的 responseContent,也会发生这种情况。我明白为什么会这样,但我想知道是否有办法访问该属性。
Thanks
谢谢
采纳答案by Matías Fidemraizer
.ReadAsAsync<T>
is an asynchronous method, meaning that it doesn't return the whole deserialized object but a Task<T>
to handle the continuation of the whole asynchronous task.
.ReadAsAsync<T>
是一种异步方法,意味着它不返回整个反序列化的对象,而是Task<T>
处理整个异步任务的延续。
You've two options:
你有两个选择:
1. Async pattern.
1. 异步模式。
Use the async
keyword in your enclousing method (for example: public async void A()
) and do the asynchronous call this way:
async
在您的封闭方法中使用关键字(例如:)public async void A()
并以这种方式进行异步调用:
dynamic responseContent = await response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;
2. Regular task API
2. 常规任务API
Or just use the Task API:
或者只使用任务 API:
response.Content.ReadAsAsync<object>().ContinueWith(task => {
// The Task.Result property holds the whole deserialized object
string returnedToken = ((dynamic)task.Result).Token;
});
It's up to you!
由你决定!
Update
更新
Before you posted the whole screenshot, no one could know that you're calling task.Wait
in order to wait for the async result. But I'm going to maintain my answer because it may help further visitors :)
在您发布整个屏幕截图之前,没有人知道您正在调用task.Wait
以等待异步结果。但我将保留我的答案,因为它可能会帮助更多的访问者:)
As I suggested in a comment to my own answer, you should try deserializing to ExpandoObject
. ASP.NET WebAPI uses JSON.NET as its underlying JSON serializer. That is, it can handle anonymous JavaScript object deserialization to expando objects.
正如我在对我自己的答案的评论中所建议的那样,您应该尝试反序列化为ExpandoObject
. ASP.NET WebAPI 使用 JSON.NET 作为其底层 JSON 序列化程序。也就是说,它可以将匿名 JavaScript 对象反序列化为 expando 对象。
回答by Rana
You can also use the similar following code to test the HttpResponseMessage using Unit Testing.
您还可以使用以下类似的代码通过单元测试来测试 HttpResponseMessage。
This worked for me.
这对我有用。
Hope this will help you
希望能帮到你
[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());
}
}
Similarly according to the need change the HttpResponseMessage in the Assert.
同样根据需要更改Assert中的HttpResponseMessage。