【问题标题】:What exactly should I test for a controller action method that returns a View with ViewModel对于返回 ViewModel 的控制器操作方法,我究竟应该测试什么
【发布时间】:2018-07-17 09:41:14
【问题描述】:

我已经为使用 Moq 框架模拟存储库的控制器操作方法编写了我的第一个单元测试。在这个测试中,我可以计算从模拟存储库返回的模型的数量,但不知道我应该执行什么测试来验证视图模型或操作结果输出?

public class HomeControllerUnitTests
{
    [Fact]
    public void IndexTest()
    {
        //Arrange
        var restaurantServiceMock = new Mock<IRestaurantDataCL>();
        var mockList = new List<Restaurant>()
        {
            new Restaurant
            {
                Id = 1,
                Name = "Sabatino's",
                Cuisine = CuisineType.French
            },
            new Restaurant
            {
                Id = 2,
                Name = "Sabatino's",
                Cuisine = CuisineType.Italian
            },
            new Restaurant
            {
                Id = 3,
                Name = "Sabatino's",
                Cuisine = CuisineType.German
            },
            new Restaurant
            {
                Id = 4,
                Name = "Sabatino's",
                Cuisine = CuisineType.None
            },
            new Restaurant
            {
                Id = 5,
                Name = "Sabatino's",
                Cuisine = CuisineType.None
            }
        };

        restaurantServiceMock
            .Setup(x => x.GetAll())
            .Returns(mockList);

        var greeterServiceMock = new Mock<IGreeter>();
        var greeterMessage = "Hello From Unit Test !!!!";
        greeterServiceMock
            .Setup(x => x.GetMessageOfTheDay())
            .Returns(greeterMessage);


        var controller = new HomeController(restaurantServiceMock.Object, greeterServiceMock.Object);

        //act
        var result = controller.Index();

        //Assert
        Assert.NotNull(result);
        var okResult = result.Should().BeOfType<ViewResult>().Subject;
        var restaurants = ((HomeIndexViewModel)okResult.Model).Restaurants.Should().BeAssignableTo<IEnumerable<Restaurant>>().Subject;
        restaurants.Count().Should().Be(5);

        var indexViewModel = okResult.Model.Should().BeAssignableTo<HomeIndexViewModel>().Subject;

        Assert.IsAssignableFrom<HomeIndexViewModel>(indexViewModel);

    }
}

【问题讨论】:

  • 不要对控制器进行单元测试。有价值的单元测试是测试业务逻辑的单元测试。您现在必须维护一个凌乱而脆弱的测试,这需要您花费大量时间来编写并且迟早会咬到您。你有什么收获?你会发现哪些可能的回归?
  • @Spotted 我可以看到并同意您的看法,即测试控制器可能会变得非常混乱。我想知道为什么有这么多教程只讨论测试控制器操作方法?是否值得写下控制器的基础测试。可能是例如返回视图名称、重定向到操作等?
  • 有这样的教程是因为不是每个人都认为在单元测试中测试控制器、使用模拟等是一种不好的做法。在某些情况下,当您有基本逻辑时,对控制器进行单元测试是有意义的(如果找到对象返回状态为 200,否则返回 404)。否则我觉得不值得。
  • 顺便说一下,你可以在unit testing阅读这一系列文章,我分享他的想法。

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


【解决方案1】:

这取决于您的控制器操作应该做什么,但是您应该例如验证是否返回了正确的视图,是否返回了正确的视图模型并断言视图模型的预期状态。有关如何对控制器进行单元测试的更多信息,请参阅文档:

https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/unit-testing/creating-unit-tests-for-asp-net-mvc-applications-cs

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing?view=aspnetcore-2.1

请记住,控制器逻辑应该是最小的。您的业​​务逻辑应在模型中实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多