我正在使用HttpClient
尝试在Web API控制器中执行POST方法。控制器方法是同步的。我是这样做的:
var response = owin.HttpClient.PostAsJsonAsync(uri, body);
之后我打电话给Wait
:
var result = response.Wait(15000);
运行此代码时,我看到http结束执行,但result
值始终为false。我能错过什么?
编辑: 我现在尝试了异步方法,但它也没有帮助我
public IHttpActionResult Add(Item item)
{
var result = _db.AddItem(item);
return Ok(result);
}
测试项目:
TestServer _owinTestServer;
public async Task<HttpResponse message> Method1(string url, object body)
{
return await
_owinTestServer.HttpClient.PostAsJsonAsync(url,body);
}
public async Task<ItemPreview> Method2(object body);
{
return await Method1("..", body ).Result.Content.ReadAsAsync<ItemPreview>();
}
[TestMethod]
public void test1()
{
Item item = new(...);
Method2(item).Continue with(task => {// Never reach here }
}
我做错了什么? 在调试时,我看到控制器方法返回了一个很好的响应,但它永远不会回到我的测试
答案 0 :(得分:10)
您正在混合异步和阻止调用(即Dialog
,.Result
),这会导致死锁。
这看起来更像是测试客户端的阻塞问题。
如果你想等待来自服务器的结果,你需要在这种情况下让测试完全异步。
将测试方法转换为异步
.Wait()
并更新方法,不要混合异步和阻止调用。
[TestMethod]
public async Task test1() {
//Arrange
Item item = new Item(...);
//Act
var preview = await Method2(item);
//Assert
Assert.IsNotNull(preview);
}
如果在调用后没有使用任务,则不需要Method1
,因此可以将其删除并让方法返回可以等待的asyn/await
Task
TestServer _owinTestServer;
public Task<HttpResponse> Method1(string url, object body) {
return _owinTestServer.HttpClient.PostAsJsonAsync(url, body);
}
需要Method2
来自await
的回复,然后获取其内容。
Method1
答案 1 :(得分:0)
控制器方法是否同步无关紧要。这纯粹是对服务器代码的关注。由于PostAsJsonAsync
方法是异步的,因此您需要await
它:
var response = await owin.HttpClient.PostAsJsonAsync(uri, body);
这将允许您的代码等待来自服务器的响应。
答案 2 :(得分:0)
我假设您的初始代码看起来像这样......
activities
是的,等待15秒后结果将是假的。这是因为您已经设置了请求A.K.A响应,但您实际上没有进行被调用和任何响应.Wait(n)将返回false。
您只需要启动ReadAsAsync ...
var categoryList = document.querySelector('#categories');
for (var i = 0; i < activitiesArray.sections.length; i++) {
categoryList.innerHTML += "<li><span>" +
activitiesArray.sections[i].category + "</span></li>";
}
--
var activitiesArray = {
sections : [
{
category: "Winter Activities",
activities: [
"Snowboarding", "Snowmobiling", "Ice Skating", "Snow Tubing", "Figure Skating", "Sledding", "Luge", "Bobsleigh", "Polar Plunge", "Ice Fishing", "Skiing"
]
},
{
category: "Music",
activities: [
"Music Festival", "Concert", "Live Music", "Opera", "Symphony", "Jam Session", "Learn an Instrument", "Musical Theatre"
]
}
]
}
但是,我认为你会发现你可以跳过响应。等等(全部),因为它将返回true,因为ReadAsAsync()将等待返回或失败。如果您正在寻找配置请求超时,您可以在HttpClient中执行此操作,并且您的ReadAsAsync将抛出一个AggregateException,其InnerException为TaskCanceledException。
另外,您不需要使用owin.HttpClient就可以实例化一个新的HttpClient。我相信你所指的owin对象是自我托管你的WebApi,我不知道这是否重要。但是,假设您在WebApi上调用Add(Item项)并且db.AddItem(item)将返回和ItemPreview对象,您的代码可能如下所示:
var response = owin.HttpClient.PostAsJsonAsync(uri, body);
var result = response.Wait(15000);
var itemPreview = response.Result.Content.ReadAsAsync<ItemPreview>();
...
答案 3 :(得分:0)
结果可能始终为false,因为_db.AddItem始终返回false。如果没有,我已经对你的代码进行了理想的更改,哪些应该对你有用
TestServer _owinTestServer;
public async Task<HttpResponse message> Method1(string url, object body)
{
return await _owinTestServer.HttpClient.PostAsJsonAsync(url,body);
}
public async Task<ItemPreview> Method2(object body);
{
return await Method1("..", body ).Result.Content.ReadAsAsync<ItemPreview>();
}
[TestMethod]
public void test1()
{
Item item = new(...);
await Method2(item).ContinueWith(task => {// Never reach here }
}
由于Method2返回Async Task,ContinueWith将不会等待它完成,因此在方法调用时可能需要等待。