今天我在使用异步 ApiControllers 创建 Web API 时遇到了问题。我正在使用 MongoDB,由于 C# 驱动程序不支持异步,我尝试在我的存储库层中实现它。
Building 存储库中生成的方法如下所示:
public async Task<IEnumerable<Building>> GetAll()
{
var tcs = new TaskCompletetionSource<IEnumerable<Building>>();
await Task.Run(() => {
var c = this.MongoDbCollection.FindAll();
tcs.SetResult(c);
});
return await tcs.Task;
}
现在,当使用 NUnit 自行测试存储库时,这非常有效。
但是当从控制器(使用 HttpClient)进行测试时,它永远不会在运行后进入“返回”行tcs.SetResult(c)
。测试一直运行,直到我手动中止它。
当我删除 Task.Run 代码并同步执行所有操作时,一切正常:
public async Task<IEnumerable<Building>> GetAll()
{
var c = this.MongoDbCollection.FindAll();
return c;
}
有谁知道为什么我在测试存储库 + 数据库和测试控制器 + 存储库 + 数据库时会遇到不同的行为?
控制器方法如下所示:(buildingRepository
使用 Ninject 在构造函数中注入)
public async Task<HttpResponseMessage> Get()
{
var result = await this.buildingRepository.GetAll();
return Request.CreateResponse(HttpStatusCode.OK, result);
}
编辑:这里也是测试方法。第一个是不工作的:(this.client
是一个 HttpClient 对象,其 accept-header 设置为"application/json"
)
[Test]
public void Get_WhenBuildingsExist_ShouldReturnBuilding()
{
var task = this.client.GetAsync("/api/building/");
var result = task.Result.Content.ReadAsStringAsync().Result;
var o = JsonConvert.DeserializeObject<IEnumerable<Building>>(result);
Assert.That(o.Any());
}
[Test]
public void Get_WhenBuildingsExist_ShouldReturnAtLeastOneBuilding()
{
var buildings = this.buildingRepository.GetAll().Result;
Assert.That(buildings.Any());
}