对抛出异常的控制器进行单元测试

2024-03-15

我有一个具有以下签名的控制器:

public CustomerTypeController(
    IHttpContextAccessor accessor,
    IPrincipalProvider provider,
    IMapper mapper, 
    ILogger<CustomerTypeController> logger,
    ICustomerTypeService customerTypeService)
{ }

现在我的Theory看起来像这样:

[Theory, AutoMoqData]
public void GetWhenHasCustomerTypesShouldReturnOneCustomerType(
    IFixture fixture,
    [Frozen] Mock<ICustomerTypeService> service,
    CustomerTypeController sut)
{
    //Arrange
    var items = fixture.CreateMany<Model.CustomerType>(3).ToList();

    //Act
    var result = sut.Get(1);

    //Assert
    Assert.IsType<OkResult>(result);
}

当我按原样运行此测试时,出现以下异常:

AutoFixture.ObjectCreationExceptionWithPath : AutoFixture 无法从 Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo 创建实例,因为创建意外失败并出现异常。请参考内部异常来排查失败的根本原因。

内部异常消息: System.Reflection.TargetInitationException:调用目标已引发异常。 System.ArgumentException:类型“System.Object”必须实现“Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder”才能用作模型绑定器。 (参数“值”)

我做错了什么,我该如何解决这个问题?


TL;DR

您应该用以下内容装饰测试方法中的控制器参数[NoAutoProperties]属性。

[Theory, AutoMoqData]
public void GetWhenHasCustomerTypesShouldReturnOneCustomerType(
    IFixture fixture,
    [Frozen] Mock<ICustomerTypeService> service,
    [NoAutoProperties] CustomerTypeController sut)
{
    //Arrange
    var items = fixture.CreateMany<Model.CustomerType>(3).ToList();

    //Act
    var result = sut.Get(1);

    //Assert
    Assert.IsType<OkResult>(result);
}

Update

现在我对 AutoFixture 代码库有了更好的了解,我想了解为什么这实际上可以解决问题。

The Greedy属性通常指示 AutoFixture 使用参数最多的构造函数,这应该与修复无关。

正如错误消息所述,当设置属性并且该属性期望实现的值时,会发生异常IModelBinder。错误的根源是BinderType的财产BindingInfo类,其类型System.Type。默认情况下 AutoFixture 将解析Type as System.Object,它解释了错误消息。

当。。。的时候Greedy应用属性后,这会使用自定义工厂自定义 AutoFixture 以创建属性类型的实例。生成的构建器图节点(可能是意外)会跳过在创建的实例上设置任何属性。

考虑到这一点,更合适的解决方案应该是使用NoAutoProperties属性。这将显式指示 AutoFixture 忽略修饰类型中的所有自动属性,但会将构造函数查询保留为“适度”。

由于在任何地方添加属性可能会变得烦人且乏味,因此我建议自定义 AutoFixture 以忽略来自的所有属性ControllerBase,在域定制中。另外,如果您使用属性注入,这将允许 AutoFixture 实例化控制器属性。

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute()
        : base(() => new Fixture().Customize(
            new CompositeCustomization(
                new AutoMoqCustomization(),
                new AspNetCustomization())))
    {
    }
}

public class AspNetCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Add(new ControllerBasePropertyOmitter());
    }
}

public class ControllerBasePropertyOmitter : Omitter
{
    public ControllerBasePropertyOmitter()
        : base(new OrRequestSpecification(GetPropertySpecifications()))
    {
    }

    private static IEnumerable<IRequestSpecification> GetPropertySpecifications()
    {
        return typeof(ControllerBase).GetProperties().Where(x => x.CanWrite)
            .Select(x => new PropertySpecification(x.PropertyType, x.Name));
    }
}

如果您需要以下属性ControllerBase由于某种原因,那么只需指示 AutoFixture 如何正确创建BindingInfo实例。


原答案

您应该用以下内容装饰测试方法中的控制器参数[Greedy]属性。

[Theory, AutoMoqData]
public void GetWhenHasCustomerTypesShouldReturnOneCustomerType(
    IFixture fixture,
    [Frozen] Mock<ICustomerTypeService> service,
    [Greedy] CustomerTypeController sut)
{
    //Arrange
    var items = fixture.CreateMany<Model.CustomerType>(3).ToList();

    //Act
    var result = sut.Get(1);

    //Assert
    Assert.IsType<OkResult>(result);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对抛出异常的控制器进行单元测试 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • asp.net core / kestrel中的线程管理

    我正在解决我们已迁移到 asp net core 2 0 的 asp net 应用程序的性能 可扩展性问题 我们的应用程序作为应用程序服务托管在 azure 上 并且在任何中等流量的情况下都很容易崩溃 让我困惑的一件事是如何处理多个并发请求
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现

随机推荐

  • 为什么 Spring 不为关系数据库提供反应式(非阻塞)客户端?

    我用过Vert x https vertx io 用于创建反应式应用程序的工具包 支持关系数据库 例如MySQL 和 Postgres https vertx io docs vertx mysql postgresql client ja
  • C# 中日期时间更改时收到通知

    最近我正在尝试制作一个日历应用程序 它将向用户显示当前的年月日期 问题是 如果用户想让我的应用程序在第二天继续运行 我如何收到通知 我该如何更改显示的日期 我不想轮询当前日期来更新它 这在c 中可能吗 注意 我尝试过系统事件 TimeCha
  • 如何将任何类型的日期转换为 dd/mm/yyyy

    我从任何日期格式的 csv 文件接收文本 例如 dd mm yy or dd mm yyyy or mm dd yyyy or 4 may 2010 我如何转换为单一类型的格式 dd mm yyyy 我正在研究 C NET 3 5 WinF
  • MPDF 在末尾显示额外的页面

    我使用 mpdf 从 html 生成 pdf 生成的 pdf 存在一个问题 即多显示一页 如果内容在第 1 页结束 则生成 2 个页面 如果内容在第 2 页结束 则生成 3 个页面 这是我的代码
  • 用于搜索网站并提取结果的 Excel 宏

    我在工作表 1 的 A1 中有一个值 它可以是企业名称 或其关联的企业编号 当网站按编号或名称搜索时 输入需要详细信息的公司名称 或编号 后 我希望能够单击 搜索 按钮并将搜索结果显示在包含 2 列的表格中 例如工作表 1 A5 B9 标签
  • mat-error 不显示错误消息 角度 5

    问题是即使我将字段留空并移至另一个字段 也不会显示错误消息 我无法找到我在这里做错了什么 任何帮助将不胜感激 如果我在 onFormValuesChanged 上放置断点 它永远不会到达断点 我尝试过在构造函数内移动表单的构建部分 但没有任
  • 在iOS项目中使用Java库

    我正在开发一个项目 需要基于相对复杂的规则集进行业务逻辑计算 计算将在以下平台上执行 安卓应用程序 iOS app Java EE 应用程序容器 业务逻辑不依赖于任何特定于平台的细节 而是严格与 数字运算 有关 为了避免 Java 和 Ob
  • 如何在多线程游戏引擎中保持世界数据同步?

    所以我试图为我想编写的游戏创建一个简单的多线程游戏引擎 到目前为止 一切都很顺利 没有任何问题 我什至知道我必须采取什么步骤才能完成它 只有一件事我不知道 好吧 从技术上讲 我知道它的解决方案 但我希望有更优雅和更快的东西 基本上 我的引擎
  • Retrofit2:将带有动态键的 JSON 转换为 Map,其中 Model 也包含这些键

    我将 Retrofit 2 与 Gson 和 RxJava 结合使用 我的 JSON 数据看起来像这样 groups 1 name First group type some data more data 2 name Second gro
  • 如何以编程方式构建pom文件的有效模型?

    我将以编程方式从 pom 文件创建有效模型 以获取 pom 模型实例中的所有继承属性 我会分析 pom 的一些属性 但我需要它的所有属性 包括 遗传的 我该怎么办 我尝试过 Sonatype Aether 但没有找到示例 您可以运行 mvn
  • 从 NSString 中删除 @"" 或将 NSString 类型转换为变量名

    我从文件中读取 NSString 然后我想将其 define 为 UIColor 以便我可以快速更改颜色 我想要像这样工作的东西 define GRAY UIColor darkGrayColor 然后从文件中读取字符串 GRAY 并将其放
  • 在kotlin中如何使用ViewModel和ViewModelProvider.AndroidViewModelFactory?

    在我当前的项目中 我使用下一行 mViewModel ViewModelProviders of this get MainViewModel class java 例如一个ViewModel but in https developer
  • CMake 是否可以始终强制编译/构建特定文件? [复制]

    这个问题在这里已经有答案了 我有一个 C 文件 使用 DATE 显示我的应用程序的构建日期 但如果这个文件没有被修改 它就不会被重建 日期也不会被更新 CMake 总是可以重建该特定文件吗 显然可以使用 makefile 如何强制 make
  • addChild的正确使用

    我是编码和 AS3 的新手 我正在阅读有关使用 AS3 将内容添加到舞台的内容 并了解了 addChild 方法 阅读更多内容后 我发现有不同的使用方法 我还读到有些方法比其他方法更好 而有些方法根本不好 最好避免 但我不相信这些消息来源
  • 如何获取枚举值的枚举定义?

    object TestEnum extends Enumeration val One Value One val Two Three Value println TestEnum One getClass println TestEnum
  • 如何从 jpeg 文件中的 FFC4 (DHT) 标头创建霍夫曼树?

    我以为我可以自己解决这个问题 但我似乎根本没有进展 好的 背景 我需要根据 jpg 文件中的 FFC4 DHT 定义霍夫曼表 标头提供的信息创建霍夫曼代码树 DHT 标头以这种方式定义 Huffman 表 1 一系列16字节 每个字节定义有
  • Pylint变量名不符合snake_case命名风格

    我收到来自 pylint 的多个警告 如下所示 变量名 df 不符合snake case命名风格 据我所知 这是因为变量名长度小于 3 个符号 但是我想使用 df i x 等变量 因此 我需要添加几个变量名称来检查异常 我尝试将该名称添加到
  • 使用 jquery 突出显示表行

    我知道有很多关于此的帖子 但我不知道为什么我的不起作用 我试图突出显示表中的一行 tr class videorow td td tr css highlight background color a8cb17 最后是我的 jQuery j
  • 如何更改Linux中ipython/jupyter笔记本使用的默认浏览器?

    我使用的是 Linux Mint 17 3 如何更改 Jupyter Notebook 使用的默认浏览器 我已将笔记本安装为 Anaconda 3 的一部分 并在我的默认浏览器 Chrome 中打开 但出于某种原因 Chrome 不允许我创
  • 对抛出异常的控制器进行单元测试

    我有一个具有以下签名的控制器 public CustomerTypeController IHttpContextAccessor accessor IPrincipalProvider provider IMapper mapper IL