【问题标题】:Wanting to Create a Unit Test for ViewComponent in ASP.NET Core 2.1想要在 ASP.NET Core 2.1 中为 ViewComponent 创建一个单元测试
【发布时间】:2018-08-02 04:48:01
【问题描述】:

在 ASP.NET Core 2.1 中,ViewComponents 与部分页面相比的一大广告优势是它们非常容易测试。我在文档中找不到任何关于如何实际测试的示例。

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

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

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);
        }

    }
}

也许这很明显,但我有点迷路了。

【问题讨论】:

  • minimal reproducible example中提供您要测试的组件的示例以及到目前为止您如何尝试测试它
  • sour repo 将测试您可以用作示例,但它们将针对组件的特定功能。 github.com/aspnet/Mvc/blob/…
  • 嗨@Nkosi,感谢您的示例,但我看不到将配置(IConfiguration)作为显示列表中测试的一部分传递到视图组件的方法。

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


【解决方案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

【讨论】:

  • 在 Core 2.1 中,他们已更改为使用 CreateWebHostBuilder,因此您的示例不再适用。另外,您是否建议不要使用构造注入?我的小例子,不是涵盖我所有案例的东西。 IConfiguration 只是一个例子。我不想为我想要测试的所有内容松散构造注入。
  • @Pete 你混淆了集成测试和单元测试。此外,我从不建议不要使用构造函数注入。我建议不要注入IConfiguration,使用显式依赖原则。
  • 谢谢@Nkosi。您将如何使用构造注入进行测试? IConfiguration 具体是什么?我不相信这会是集成测试,因为构造函数中的值会改变组件的行为。
  • @Pete 我已经在我的回答中展示了如何测试它。模型被注入到组件的构造函数中。无需将组件耦合到IConfiguration
  • 尊敬的,不,你没有。我正在寻求有关如何对具有 IConfiguration 或任何其他服务注入构造函数的视图组件进行单元测试的帮助。不是作为构造函数参数传入的简单模型。我并不是要就这是否是个好主意征求意见。在 Microsoft 策划的博客上就是那个确切的例子,但没有测试(这是我正在寻找的)。 blogs.technet.microsoft.com/dariuszporowski/…
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
相关资源
最近更新 更多