c# - 我应该如何对返回模型的 Controller 进行单元测试?

标签 c# asp.net-mvc unit-testing

我有一个名为 PostsController 的 Controller

public class PostsController : Controller
{
    private readonly IPostsRepository repository;

    public PostsController(IPostsRepository repository)
    {
        this.repository = repository;
    }

    public ViewResult Index()
    {
        var posts =
            repository.All()
                      .OrderBy(post => post.PublishedAt);

        return View("Index", posts.MapTo<PostViewModel>());
    }
}

还有一个名为 PostsControllerTest

的相应测试夹具
[TestFixture]
public class PostsControllerTest
{
    private PostsController controller;
    private Mock<IPostsRepository> repository;

    [SetUp]
    public void SetUp()
    {
        AutoMapperConfig.Configure();
        repository = new Mock<IPostsRepository>();
        controller = new PostsController(repository.Object);
    }

    [Test]
    public void Index_ReturnsCorrectModel()
    {
        var actual = controller.Index().Model;

        Assert.IsAssignableFrom<IEnumerable<PostViewModel>>(actual);
    }
}

目前我只测试 Controller 是否返回正确的模型类型。我是否还应该 stub 存储库并测试是否返回了正确的数据,如下所示:

[Test]
public void Index_ReturnsCorrectModel()
{
    var post = new Post
    {
        Slug = "continuing-to-an-outer-loop",
        Title = "Continuing to an outer loop",
        Summary = "When you have a nested loop, sometimes",
        Content = "When you have a nested loop, sometimes",
        PublishedAt = DateTime.Now.AddDays(7),
        Tags = new Collection<Tag> { new Tag { Name = "Programming" } }
    };
    repository.Setup(repo => repo.All()).Returns(new[] { post });

    var actual = controller.Index().Model as IEnumerable<PostViewModel>;
    Assert.NotNull(actual);
    Assert.AreEqual(1, actual.Count());
    Assert.AreEqual(post.Title, actual.First().Title);
}

我感到非常沮丧,因为我不知道自己是否进行了正确的单元测试。清楚地解释我应该采取哪种方法,为什么会非常有帮助。

最佳答案

我认为您不需要测试 IPostRepository 的功能在这个单元测试中。您应该为它创建一个单独的单元测试类。

MapTo<T> 的功能类似应该单独测试。

单元测试应该只测试 SUT(被测系统)的功能,在本例中是 Index你的方法PostsController类。

这是一个简单的方法,因此您要在此单元测试中验证的两件事是:

1- repository.All()方法被调用一次

2- 您的 View 模型已正确映射(您已经在做)

这就是我对该方法进行单元测试的方式:

[Test]
    public void Index_ReturnsCorrectModel()
    {
        // Arrange
        repository.Setup(repo => repo.All()).Returns(Enumerable.Empty<Post>());

        // Act
        var actual = controller.Index().Model;

        // Assert
        Assert.IsAssignableFrom<IEnumerable<PostViewModel>>(actual);
        repository.Verify(repo => repo.All(), Times.Once);
    }

此外,为了尽量减少安排单元测试所需的工作量,可以使用像 AutoFixture 这样的库,它会自动为您创建 post 对象。

关于c# - 我应该如何对返回模型的 Controller 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25105161/

相关文章:

c# - WPF滚动条样式问题

c# - NDatabase 在 Order By 上崩溃

java - Controller 测试模拟装置

c# - 如何摆脱异常 "The ' Microsoft.ACE.OLEDB.12。 Win 7 中的 0' provider is not registered on the local machine"

c# - C#中的string[][]和string[,]有什么区别

c# - IIS默认80端口中的RDLC报告查看问题

asp.net-mvc - Windows Azure 上使用 Entity Framework 进行 Asp.net mvc 身份验证

asp.net-mvc - 从 web.Config 在 Controller 级别授权用户

angular - 类型错误 : Cannot read properties of undefined (reading '<myvariable>' )

unit-testing - 测试驱动开发中测试列表的概念