简体   繁体   English

如何测试异步任务<IActionResult>返回 IEnumerable<model> 在 xunit 中使用最小起订量?

[英]How to test async Task<IActionResult> returning IEnumerable<model> using moq in xunit?

I want to test GetMoviesAsync of my Controller.我想测试我的控制器的 GetMoviesAsync。 I don't know where I am doing wrong in my Moq setup.我不知道我在 Moq 设置中做错了什么。 I am getting 0 item from GetMoviesAsync.我从 GetMoviesAsync 获得 0 个项目。

What am I doing wrong?我究竟做错了什么?

// Api-Controller: // API 控制器:

   public interface ICommand
   {
        Task<IEnumerable<Movie>> GetMoviesAsync();
   }

   public class SampleController : ControllerBase
    {
        private readonly ICommand movieCommand;

        public SampleController(ICommand command)
        {
            movieCommand = command;
        }

        [HttpGet]
        public async Task<IActionResult> GetMoviesAsync()
        {
            var movies = await movieCommand.GetMoviesAsync();
            return Ok(movies);
        }
    }

// Unit-Test: // 单元测试:

public class SampleControllerTest
    {
        private IEnumerable<Movie> MovieList()
        {
            IList<Movie> movies = new List<Movie>()
            {
                new Movie()
                {
                    ID =1,
                    Title = "Test",
                    ReleaseDate = DateTime.Now,
                    RunningTimeInMinutes = 100
                }
            };
            return movies;
        }

        private SampleController GetSampleController()
        {
            var command = new Mock<ICommand>();

            return new SampleController(command.Object);
        }

        [Fact]
        public async Task GetMovies_Test()
        {
            // Arrange
            var controller = GetSampleController();
            var commadMock = new Mock<ICommand>();
            // How to setup moq here?
            commadMock.Setup(s => s.GetMoviesAsync()).Returns(Task.FromResult<IEnumerable<Movie>>(MovieList())).Verifiable();
            // Act
            var response = await controller.GetMoviesAsync() as OkObjectResult;
            // Problem is here, 
            var li=response.Value as IEnumerable<Movie>;
         }
    }

What am I doing wrong?我究竟做错了什么?

Two completely different mocks are being used.正在使用两个完全不同的模拟。

One is used to create the controller一个用于创建控制器

private SampleController GetSampleController()
{
    var command = new Mock<ICommand>();

    return new SampleController(command.Object);
}

and another is being created and setup in the test.另一个正在测试中创建和设置。

var controller = GetSampleController();
var commadMock = new Mock<ICommand>();
// How to setup moq here?
commadMock.Setup(s => s.GetMoviesAsync()).Returns(Task.FromResult<IEnumerable<Movie>>(MovieList())).Verifiable();

To solve this, use the same mock to get the desired behavior要解决此问题,请使用相同的模拟来获得所需的行为

[Fact]
public async Task GetMovies_Test() {
    // Arrange
    var commadMock = new Mock<ICommand>();
    var controller = new SampleController(commadMock.Object); //<---
    commadMock
        .Setup(_ => _.GetMoviesAsync())
        .ReturnsAsync(MovieList())
        .Verifiable();

    // Act
    var response = await controller.GetMoviesAsync() as OkObjectResult;

    //Assert
    var list = response.Value as IEnumerable<Movie>;

    //...
 }

Note the use of ReturnsAsync to setup the returned Task注意使用ReturnsAsync来设置返回的Task

It seems that you are not using the correct mock on the Controller.您似乎没有在控制器上使用正确的模拟。 The one that you are using does not have any setup on top of the method GetMoviesAsync您使用的那个在方法 GetMoviesAsync 之上没有任何设置

For me helped almost the solution offered by Nkosi but with little difference对我来说,几乎帮助了 Nkosi 提供的解决方案,但差别不大

[Fact]
public async Task GetMovies_Test() {
    // Arrange
    var commadMock = new Mock<ICommand>();
    var controller = new SampleController(commadMock.Object); //<---
    commadMock
        .Setup(_ => _.GetMoviesAsync())
        .ReturnsAsync(MovieList());

    // Act
    var response = await controller.GetMoviesAsync();

    //Assert
    var returnValue = Assert.IsType<ViewResult>(response);

    var model = returnValue.Model as IEnumerable<Movie>;

    //...
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM