想要在ASP.NET Core 2.1中为ViewComponent创建单元测试

时间:2018-08-02 04:48:01

标签: razor asp.net-core asp.net-core-viewcomponent

与ASP.NET Core 2.1中的部分页面相比,ViewComponents所宣称的最大好处之一是它们很容易测试。我在文档中找不到任何有关如何实际测试的示例。

我的ViewComponent在其构造函数中采用了IConfiguration,因此我可以注入AppSetting值。它通过Invoke传递的几个参数执行。我假设我想以某种方式测试返回视图的模型,并确保它是我所期望的(基于AppSettings和这两个参数)。

[编辑] 这是一个使用配置服务的简单ViewComponent示例,并将参数传递给invoke。

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace WebApp.Pages.Components.RatingControl
{

    public class MyModel
    {
        public string MyVal1 { get; set; }
        public string MyVal2 { get; set; }
    }

    public class MyViewData
    {
        public MyModel MyModel { get; set; }
        public string Param1 { get; set; }
    }
    public class SimpleViewComponent : ViewComponent
    {
        private readonly MyModel _myModel;

        public SimpleViewComponent(IConfiguration config)
        {
            _myModel = new MyModel
            {
                MyVal1 = config["myVal1"],
                MyVal2 = config["myVal2"],
            };
        }

        public IViewComponentResult Invoke(string param1)
        {
            var myViewData = new MyViewData
            {
                MyModel = _myModel,
                Param1 = param1
            };

            return View(myViewData);
        }

    }
}

也许很明显,但我在这里有些迷茫。

1 个答案:

答案 0 :(得分:1)

实际上不应将IConfiguration作为依赖项传递。您已经有一个要填充的模型,因此可以利用配置框架的绑定功能,并在启动时从配置中显式注入该填充的模型。

所以假设您的 appsetting.json 文件

{
  ...

  "myval1": "value1",
  "myval2": "value2",

  ...
}

和现有的MyModel,您可以按照文档中建议的做法从配置开始绑定对象图。

var builder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json");

Configuration = builder.Build();

var myModel = new MyModel();
Configuration.Bind(myModel);

然后您将在服务集合中注册模型应用程序设置

services.AddSingleton(myModel);

由于框架使用依赖项注入来初始化视图组件。

现在真的不需要将IConfiguration注入视图组件,因为可以将模型作为显式依赖项注入

public class SimpleViewComponent : ViewComponent {
    private readonly MyModel model;

    public SimpleViewComponent(MyModel model) {
        this.model = model;
    }

    public IViewComponentResult Invoke(string param1) {
        var myViewData = new MyViewData {
            MyModel = model,
            Param1 = param1
        };
        return View(myViewData);
    }
}

所有这些操作将使隔离视图中的组件的单元测试变得相当容易,因为初始化模型的假实例很简单。

//Arrange
var model = new MyModel {
    MyVal1 = "test1",
    MyVal2 = "test2",
}

var viewComponent = new SimpleViewComponent(model);
var param1 = "param1";

//Act
var result = viewComponent.Invoke(param1);

//Assert
result.Should().NotBeNull();
result.ViewData.Model
    .Should().NotBeNull()
    .And.BeOfType<MyViewData>();
//...other assertions