Task.Run никогда не завершается при тестировании с использованием HttpClient

Сегодня я столкнулся с проблемой при создании веб-API с использованием асинхронных ApiControllers. Я использую 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 -, установленным на"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());
}
7
задан azzlack 14 August 2012 в 08:55
поделиться