首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从通过单元测试API返回的Task<IActionResult>中获取值

如何从通过单元测试API返回的Task<IActionResult>中获取值
EN

Stack Overflow用户
提问于 2018-06-11 23:20:30
回答 4查看 44.4K关注 0票数 28

我已经使用ASP.NET MVC Corev2.1创建了一个应用程序接口。我的一个HttpGet方法设置如下:

代码语言:javascript
复制
public async Task<IActionResult> GetConfiguration([FromRoute] int? id)
{
    try
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        ..... // Some code here

        return Ok(configuration);
    }
    catch (Exception ex)
    {
        ... // Some code here
    }
}

在单元测试时,我可以检查Ok是响应,但我真的需要查看配置的值。我似乎不能让它在以下情况下工作:

代码语言:javascript
复制
[TestMethod] 
public void ConfigurationSearchGetTest()
{
    var context = GetContextWithData();
    var controller = new ConfigurationSearchController(context);
    var items = context.Configurations.Count();
    var actionResult = controller.GetConfiguration(12);

    Assert.IsTrue(true);
    context.Dispose();
}

在运行时,我可以检查actionResult是否有一些我无法编码的值。我是不是做错了什么?或者我只是想错了?我希望能够做到:

代码语言:javascript
复制
Assert.AreEqual(12, actionResult.Values.ConfigurationId);
EN

回答 4

Stack Overflow用户

发布于 2018-06-12 06:55:27

您可以在不更改返回类型的情况下获得经过测试的控制器。

IActionResult是所有其他类型的基类型。

将结果转换为预期类型,并将返回值与预期值进行比较。

因为您测试的是异步方法,所以也要使测试方法异步。

代码语言:javascript
复制
[TestMethod] 
public async Task ConfigurationSearchGetTest()
{
    using (var context = GetContextWithData())
    {
        var controller = new ConfigurationSearchController(context);
        var items = context.Configurations.Count();

        var actionResult = await controller.GetConfiguration(12);

        var okResult = actionResult as OkObjectResult;
        var actualConfiguration = okResult.Value as Configuration;

        // Now you can compare with expected values
        actualConfuguration.Should().BeEquivalentTo(expected);
    }
}
票数 44
EN

Stack Overflow用户

发布于 2018-06-11 23:46:09

良好的实践表明,您在控制器操作中没有太多代码要测试,而大部分逻辑都在其他地方的解耦对象中,这些对象更容易测试。话虽如此,如果您仍然想测试您的控制器,那么您需要进行测试async并等待调用。

你会遇到的一个问题是,你使用的是IActionResult,因为它允许你返回BadRequest(...)Ok(...)。但是,由于您使用的是ASP.NET MVC Core2.1,因此您可能希望开始使用新的ActionResult类型。这应该有助于您的测试,因为您现在可以直接访问强类型返回值。例如:

代码语言:javascript
复制
//Assuming your return type is `Configuration`
public async Task<ActionResult<Configuration>> GetConfiguration([FromRoute] int? id)
{
    try
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        ..... // Some code here

        // Note we are now returning the object directly, there is an implicit conversion 
        // done for you
        return configuration;
    }
    catch (Exception ex)
    {
        ... // Some code here
    }
}

注意,我们现在直接返回对象,因为有一个implicit conversion from Foo to ActionResult

现在,您的测试可以如下所示:

代码语言:javascript
复制
[TestMethod] 
public async Task ConfigurationSearchGetTest()
{
    var context = GetContextWithData();
    var controller = new ConfigurationSearchController(context);
    var items = context.Configurations.Count();

    // We now await the call
    var actionResult = await controller.GetConfiguration(12);

    // And the value we want is now a property of the return
    var configuration = actionResult.Value;

    Assert.IsTrue(true);
    context.Dispose();
}
票数 15
EN

Stack Overflow用户

发布于 2018-06-11 23:27:31

您需要等待对GetConfiguration的调用才能获得IActionResult对象,如下所示:

代码语言:javascript
复制
var actionResult = await controller.GetConfiguration(12);

为此,您需要将测试方法的签名也更改为异步。因此,请更改以下内容:

代码语言:javascript
复制
public void ConfigurationSearchGetTest()

要这样做:

代码语言:javascript
复制
public async Task ConfigurationSearchGetTest()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50801094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档