无法从'Microsoft.AspNetCore.Mvc.ActionResult'转换为'System.Collections.Generic.IEnumerable <string>'

时间:2018-08-14 08:07:54

标签: c# unit-testing asp.net-core .net-core

我在控制器中有一个异步方法,该方法从客户端调用该方法。我想在foreach循环中遍历此方法,但出现错误:

*Cannot convert from 'Microsoft.AspNetCore.Mvc.ActionResult' to 'System.Collections.Generic.IEnumerable<string>'*

UnitTest.cs

[TestFixture]
    public class ClientUnitTests 
    {
        private MessagesController Controller = new MessagesController(null, null, null);

        [Test]
        public async Task Check_API_Links()
        {
            // Arrange
            List<IEnumerable<string>> reporteeList = new List<IEnumerable<string>>();

            var links = await Controller.GetLinks();
            reporteeList.Add(links); //Cannot convert from 'Microsoft.AspNetCore.Mvc.ActionResult' to 'System.Collections.Generic.IEnumerable<string>'
            foreach (var itemLink in reporteeList)
            {
                reporteeList.Add(itemLink);
            }

            // Assert
            Assert.IsNotNull(reporteeList);
            Assert.GreaterOrEqual(0, reporteeList.Count);
            Assert.IsInstanceOf<IEnumerable<string>>(reporteeList);
        }
}

Controller.cs

[HttpGet]
 public async Task<ActionResult> GetLinks()
 {
   var result = await _client.GetLinks();

    return Ok(result);
 }

Client.cs

public async Task<ActionResult<IEnumerable<string>>> GetLinks()
{
   // Some logic here, 
}

我该如何解决此问题以在单元测试中迭代出问题的GetLinks方法?

谢谢。

4 个答案:

答案 0 :(得分:1)

假设.NET Core 2.1

public async Task<ActionResult<IEnumerable<string>>> GetLinks()

或更不受欢迎的

public async Task<IActionResult> GetLinks()

答案 1 :(得分:1)

对于您的问题,您将ActionResult<IEnumerable<string>>嵌入Ok,将List<IEnumerable<string>>嵌入IEnumerable<string>

对于当前设计,请尝试以下代码:

        List<IEnumerable<string>> reporteeList = new List<IEnumerable<string>>();
        var result = await controller.GetLinks();
        var links = ((ObjectResult)((ActionResult<IEnumerable<string>>)((ObjectResult)result).Value).Result).Value as IEnumerable<string>;
        reporteeList.Add(links);

但是,在我的选择中,您不应该使用embed对象。请检查以下设计是否满足您的要求。

Client.cs返回IEnumerable<string>而不是ActionResult<IEnumerable<string>>

public class Client
{
    public async Task<ActionResult<IEnumerable<string>>> GetLinks()
    {
        IEnumerable<string> links = new List<string>() {
            "L1","L2"
        };
        return new ObjectResult(links);
        // Some logic here, 
    }
    public async Task<IEnumerable<string>> GetLinks1()
    {
        IEnumerable<string> links = new List<string>() {
            "L1","L2"
        };
        return links;
        // Some logic here, 
    }
}

控制器

    public async Task<ActionResult> GetLinks1()
    {
        var result = await new Client().GetLinks1();
        return Ok(result);
    }

测试

        List<string> reporteeList1 = new List<string>();
        var result1 = await controller.GetLinks1();
        var links1 = result1 as ObjectResult;
        reporteeList1.AddRange((IEnumerable<string>)links1.Value);

答案 2 :(得分:0)

仅存在从T到ActionResult<T>的隐式转换。要从ActionResult中获取价值,您需要将ActionResult显式转换为通用版本ActionResult<T>,然后获取ActionResult<T>.Value

List<IEnumerable<string>> reporteeList = new List<IEnumerable<string>>();
var links = (ActionResult<IEnumerable<string>)(await Controller.GetLinks());

reporteeList.Add(links.Value);

尽管如果您在Controller中将GetLinks签名更改为也使用通用结果版本,则可以避免强制类型转换:

public async Task<ActionResult<IEnumerable<string>>> GetLinks()

答案 3 :(得分:0)

测试

    [Fact]
    public async Task Get_WhenCalled_ReturnsAllItemsCount()
    {
           // Act
       
        var result = await _controller.GetLinks1();
        var okResult = result.Result as OkObjectResult;

        // Assert
        var items = Assert.IsType<List<string>>(okResult.Value);
        Assert.Equal(2, items.Count);
    }