Как выполнить юнит-тестирование действия с типом возврата ActionResult <T>? - PullRequest
0 голосов
/ 20 ноября 2018

Мой вопрос очень похож на этот:

Как выполнить модульное тестирование действия, когда типом возврата является ActionResult?

Проблема в том, что мой вопрос смешивается в типе generic ActionResult<T>, async и Ok(...).Я не могу адаптировать ответ на связанный вопрос к общей ситуации.Или, возможно, мой сценарий несколько отличается.

Вот репродукция.Создать новое базовое веб-приложение ASP.NET типа «API».Добавьте в решение новый тестовый проект xUnit .NET Core, который ссылается на проект API (а также все необходимые библиотеки фреймворков).Создайте контроллер и выполните следующие тесты, соответственно:

public class Thing { public string Name => "Foobar"; }
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<Thing>> Get()
    {
        // The real "Thing" would be asynchronously retrieved from the DB
        return Ok(new Thing());
    }
}
[Fact]
public async Task Test1()
{
    var controller = new ValuesController();
    var actionResult = await controller.Get();
    Assert.NotNull(actionResult.Value);
    Assert.Equal("Foobar", actionResult.Value.Name);
}

Вместо того, чтобы стать зелёным, этот тест не пройдёт для утверждения NotNull (или, если яне будет иметь этого утверждения, он выдает NullReferenceException).

После отладки и проверки иерархии классов, я обнаружил, что это, кажется, дает желаемые результаты:

[Fact]
public async Task Test1()
{
    var controller = new ValuesController();
    var actionResult = await controller.Get();
    var okResult = actionResult.Result as OkObjectResult;
    var realResult = okResult?.Value as Thing;
    Assert.Equal("Foobar", realResult?.Name);
}

Но этоТакое чувство, что я делаю что-то не так.Практически у меня остались два связанных вопроса:

  1. Есть ли другой идиоматический способ написания этого теста, который сворачивает все эти as приведения?
  2. Почему первый примеркомпилировать, но дать исключение во время выполнения?Что здесь происходит?

1 Ответ

0 голосов
/ 20 ноября 2018

С XUnit вы можете использовать T t = Assert.IsType<T>(other).Это будет выполнять приведение, если это возможно, но в противном случае это приведет к сбою теста.

Например, я делаю что-то вроде этого:

IActionResult actionResult = await Controller.GetItem(id);
OkObjectResult okObjectResult = Assert.IsType<OkObjectResult>(actionResult);
Model model = Assert.IsType<Model>(okObjectResult.Value);
Assert.Equal(id, model.Id);

Что касается вашего 2-го вопроса, вещи могут броситьисключение нулевой ссылки во время выполнения и компиляция правильно.Эта проблема будет решена с C # 8 и необнуляемыми типами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...