【问题标题】:How to convert OkObjectResult to a List<>?如何将 OkObjectResult 转换为 List<>?
【发布时间】:2020-08-07 03:53:12
【问题描述】:

目前正在编写单元测试以检查它是否返回正确的场所类型

[Fact]
    public async Task GetVenue_Should_Return_GetVenueType()
    {
        var venues = new[]
        {
            new VenueTypeResponse()
            {
                id = 1,
                Name = "Cafe",
                ImageUrl = "Cafe.png"
            },
            new VenueTypeResponse()
            {
                id = 2,
                Name = "Takeaway",
                ImageUrl = "Takeaway.png"
            }
        };

        mockedVenueService.Setup(x => x.GetVenueType()).Returns(Task.FromResult(new List<VenueTypeResponse>(venues)));

        var controller = new VenueController(mockedVenueService.Object, mockedCafeService.Object, mockedCafeRequestValidator.Object);

        var result = await controller.GetVenueType() as OkObjectResult;
        var data = result.Value as List<VenueTypeResponse>; //errors here: outputs null
                  
        Assert.IsType<OkObjectResult>(result);

        Assert.Collection(data, x => Assert.Contains("Cafe", x.Name),
                                x => Assert.Contains("Takeaway", x.Name));
        Assert.Collection(data, x => Assert.Contains("Cafe.png", x.ImageUrl),
                                x => Assert.Contains("Takeaway.png", x.ImageUrl));

        Assert.Equal(StatusCodes.Status200OK, result.StatusCode);
        
    }

当我尝试在数据变量中转换 OkObjectResult 时,它只输出 null?

我在转换过程中是否做错了什么?

GetVenueType()的实现

    [HttpGet]
    [Route("venue-type")]
    [ProducesResponseType(typeof(VenueTypeResponse), 200)]
    [ProducesResponseType(401)]
    public async Task<IActionResult> GetVenueType()
    {
        var result = new VersionResponse()
        {
            Data = await _venueService.GetVenueType()

        };
        return Ok(result);
    }

【问题讨论】:

  • 我在这里没有看到关于转换/转换的任何问题,我在测试中做了很多同样的事情。你能和我们分享一下你对GetVenueType的行动实施吗?
  • 你为什么期待 OkObjectResult?
  • @MuhammadVakili 刚刚更新了

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


【解决方案1】:

问题在于您的投射,您在控制器中返回VersionResponse 中的OkObjectResult,但试图将其投射到List&lt;VenueTypeResponse&gt;

在您的测试方法中,您应该将resultValue 转换为VersionResponse,如下所示:

 var data = result.Value as VersionResponse;

您应该将断言更改为:

Assert.Collection(data.Data, x => Assert.Contains("Cafe", x.Name),
    x => Assert.Contains("Takeaway", x.Name));
Assert.Collection(data.Data, x => Assert.Contains("Cafe.png", x.ImageUrl),
    x => Assert.Contains("Takeaway.png", x.Data.ImageUrl));

【讨论】:

  • 我将如何为列表做断言?例如我不能再使用 Assert.Collection
  • 你应该在Assert.Collection 中使用data.Data 而不是data 本身,@JamesMcCoy
  • 给出错误 - 不能使用 lambda 表达式作为动态分派操作的参数,除非先将其转换为委托或表达式树类型。 proj.UnitTests
  • .Data 实际上是动态类型的
【解决方案2】:

你的意思是你不能从 OkObjectResult 中获取 List?这里有一个从 OkObjectResult 获取列表的演示:

测试控制器:

public async Task<IActionResult> GetVenueType()
{
    List<Spray> sprays = new List<Spray> { new Spray { Id = 1, Name = "product1", Price = 10, Quantity = 1, Total = 1, Image = "image1.png" }, new Spray { Id = 2, Name = "product2", Price = 20, Quantity = 1, Total = 20, Image = "Image2.png" } };
    return Ok(sprays);
}

public ActionResult TestOK()
{
    IActionResult result = new TestController().GetVenueType().Result;
    var data = result as OkObjectResult;
    List<Spray> sprays = (List<Spray>)data.Value;
    List<Spray> ss = sprays.Where(s => s.Name.Contains("product1")).ToList<Spray>();

    return Ok(ss);
}

结果:

【讨论】:

  • 我几乎从下面的答案中得到了代码,但是当我尝试对数据变量执行 Assert.Collection 时出现错误
  • 我该如何做一个断言来检查正文的内容?
  • 我已经更新了我的答案,我可以使用 linq (sprays.Where(xxxxx).ToList()) 来查看喷雾列表。
猜你喜欢
  • 2020-11-27
  • 2021-11-14
  • 1970-01-01
  • 2018-12-27
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多