为什么应该用record来定义DTO(续)

前言

上次,我们介绍了因为DTO的“不变性”,应该用record来定义DTO。

今天,我们来说明用record来定义DTO的另一个好处。

问题

首先,我们实现一个Controler,代码如下:

[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{private readonly IMediator _mediator;public UserController(IMediator mediator){this._mediator = mediator;}[HttpGet("{id}")]public async Task<UserDto> GetById(int id){var request = new GetUserByIdQuery { Id = id };var result = await this._mediator.Send(request);return result;}
}public class UserDto
{public int Id { get; set; }public string Name{ get; set; }
}public class GetUserByIdQuery : IRequest<UserDto>
{public int Id { get; set; }
}

这里,IRequest<T>可以认为是DTO。

然后,我们编写测试用例:

[Fact]
public async void Test1()
{var mediatorMock = new Mock<IMediator>();var request = new GetUserByIdQuery { Id = 1};var expectedUser = new UserDto { Id = 1, Name = "My IO" };mediatorMock.Setup(x => x.Send(request, default(CancellationToken))).Returns(Task.FromResult(expectedUser));var controller = new UserController(mediatorMock.Object);var result = await controller.GetById(1);Assert.Equal(expectedUser, result);
}

我们Mock了IMediator,期望它执行Send后返回expectedUser。

看起来都没有问题,但是测试执行失败:

调试代码,可以看到传递的参数是正确的,但是返回值是null:

这说明实际没有命中mediatorMock.Setup中的方法。

这是为什么呢?

原因

原因其实是,x.Send(request, default(CancellationToken))表示必须完全匹配才能返回指定的结果,但是request和GetById方法中创建的request其实是2个不同的实例,.NET并不认为它们相等。

虽然可以修改mediatorMock.Setup方法来修复测试。

但对于我来说,属性值完全相同的DTO应该就是相等的,可以让类实现值相等性来解决:

public class GetUserByIdQuery : IRequest<UserDto>
{public int Id { get; set; }public override bool Equals(object obj) => this.Equals(obj as GetUserByIdQuery);public bool Equals(GetUserByIdQuery p){if (p is null){return false;}if (Object.ReferenceEquals(this, p)){return true;}if (this.GetType() != p.GetType()){return false;}return Id == p.Id;}public override int GetHashCode() => Id.GetHashCode();
}

但是,为每个DTO重写EqualsGetHashCode也不是个事。

record的相等性

其实,更简单的解决方法是修改定义如下:

public record GetUserByIdQuery : IRequest<UserDto>
{public int Id { get; set; }
}

你会发现测试通过了。

这是因为,record在设计上就具备创建具有值相等数据类型的能力,编译器会自动生成样板代码

结论

在本文中,我们介绍了通过使用record类型,可以大大简化定义实现值相等性DTO的代码量。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299649.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

资料分享 | 数学建模竞赛备战大全

全世界只有3.14 % 的人关注了青少年数学之旅目前针对数学建模的认知&#xff0c;绝大部分人还停留在数学建模竞赛阶段&#xff0c;并不知道数学建模是数据领域非常重要的一种方法。数学建模涉及的内容广泛&#xff0c;比如碎纸片问题中所涉及的图像识别及神经网络、小区开放问题…

初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来

这里我要明说一下&#xff0c;不是Java初级和学习Java的千万不要乱看&#xff0c;否则~~~~ 你会怀疑人生&#xff0c;因为会浪费你时间啊&#xff01;&#xff01;&#xff01; 本次考点是Java初级开发工程师面试必备的一些东西!!! 1、数据类型 基本类型 byte/8、short/16、…

数学2600年,欧拉凭什么能当上“大王”?

全世界只有3.14 % 的人关注了青少年数学之旅何为数学&#xff1f;♠音乐家说&#xff0c;数学是世界上最和谐动听的音符♥植物学家说&#xff0c;世界上没有比数学更美的花朵♣美学家说&#xff0c;哪里有数学&#xff0c;哪里才有真正的美♦哲学家说&#xff0c;世界什么都在变…

NET流行高性能JSON框架-Json.NET

在日常编程中经常会使用到Json来进行数据的交互好在.Net平台下有很多开源的Json库使得我们能够比较轻松快速的处理各种复杂的Json&#xff0c;其中Newtonsoft库是NET的流行高性能JSON框架特性工具VS2010Newtonsoft库从NuGet下载合适的Newtonsoft.Json库1.在你需要引用Newtosoft…

Scribefire发CSDN博客

历史在非常久非常久曾经&#xff0c;CSDN是支持外部工具来写文章的&#xff0c;但是在还有一个非常久非常久曾经就不行了。突然看到CSDN有能够用外部工具来写博客了&#xff08;CSDN的公告&#xff09;&#xff0c;一直以来都纠结这个问题&#xff0c;CSDN的编辑器不好用&#…

今日笔记!——分析Java应用性能

1 问题描述 因产品架构的复杂性&#xff0c;可能会导致性能问题的因素有很多。根据部署架构&#xff0c;大致的可以分为应用端瓶颈、数据库端瓶颈、环境瓶颈三大类。可以根据瓶颈的不同部位&#xff0c;选择相应的跟踪工具进行跟踪分析。 应用层面瓶颈大致有如下两类&#xf…

除了PS,还有它可以轻松实现图像处理!

全世界只有3.14 % 的人关注了青少年数学之旅在我们生活中&#xff0c;常见的图像处理软件有Adobe Photoshop、Adobe Illustrator等。然而&#xff0c;并非只有软件才能实现图像处理&#xff0c;通过编程手段也是能实现的&#xff01;今天&#xff0c;小天将要带着大家走进计算机…

微服务并不能解决你的烂代码问题

点击上方蓝字关注我们“微服务并不能解决你的烂代码问题很久以来&#xff0c;软件的交付质量一直是一个大家比较关心的问题&#xff0c;而程序员和架构师也一直在极力寻找一种更好的方式来构建应用系统。随着互联网爆炸式的增长&#xff0c;对于系统的交付速度和质量的要求也日…

protobuf在java应用中通过反射动态创建对象

2019独角兽企业重金招聘Python工程师标准>>> ---恢复内容开始--- 最近编写一个游戏用到protobuf数据格式进行前后台传输&#xff0c;苦于protobuf接受客户端的数据时是需要数据类型的如xxx.parseForm(...),这样就要求服务器在接受客户端请求时必须知道客户端传递的数…

黑科技轮胎:有能发电的,脑洞简直不要太大...

全世界只有3.14 % 的人关注了青少年数学之旅人类历史上的很多伟大发明&#xff0c;都是由脑洞产生的&#xff0c;这样那样&#xff0c;然后问题就解决了&#xff0c;过程很复杂&#xff0c;却又很简单&#xff0c;甚至有时候&#xff0c;是一种很奇葩的方式。在漫长的历史进程中…

VS 2019 16.11正式发布 | 新功能(Hot Reload 热重载)试用

VS 2019 16.11VS 2019 16.11已于2021.8.10正式发布。&#xff08;https://devblogs.microsoft.com/visualstudio/visual-studio-16-11/&#xff09;这个版本主要包括以下内容&#xff1a;Visual Studio中的Git工具体验改进支持.NET应用程序的Hot Reload&#xff08;热重载&…

测试String, StringBuilder,StringBuffer 的数据,我居然发现这些了~~

懒的搞什么开头了&#xff0c;直接撸代码吧 想了想还是给大家看看学姐照片吧&#xff0c;保持眼睛的明亮&#xff0c;代码敲多了&#xff0c;伤眼 1&#xff1a; 作StringBuilder与String的拼接比较 Test public void testString () {String s"";long begin S…

厉害了!这里藏着通关学霸的秘籍

全世界只有3.14 % 的人关注了青少年数学之旅在这个资讯丰富且易获取的时代&#xff0c;越来越多的人不愿意花时间阅读书籍&#xff0c;碎片化阅读成了主流。人们获取的东西多而杂&#xff0c;很难系统、全面。海量信息对人是冲击&#xff0c;更是诱惑。谁不想了解天下奇闻&…

『 编程思维』之我见

编程思维&#xff0c;对于一个开发人员来说是必备的&#xff0c;但凡能让应用跑起来&#xff0c;不管应用的大小&#xff0c;优劣&#xff0c;说明这个开发人员都具有编程思维&#xff0c;毕竟程序认可了这个开发人员逻辑&#xff0c;能启动起来。小到几行代码&#xff0c;一个…

史上最全图详解Jvm—诊断工具和JVM监控

3.1. 工具概述 使用上一章命令行工具或组合能帮您获取目标Java应用性能相关的基础信息&#xff0c;但它们存在下列局限&#xff1a; 1&#xff0e;无法获取方法级别的分析数据&#xff0c;如方法间的调用关系、各方法的调用次数和调用时间等&#xff08;这对定位应用性能瓶颈至…

去医院看病如何开开心心出来? | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源百度弱智吧&#xff0c;侵权删&#xff09;

玩机器学习,能不知道它?

推荐一个端对端的开源机器学习平台编程导航 致力于推荐优质编程资源 ????项目开源仓库&#xff1a;https://github.com/liyupi/code-nav跪求一个 star ⭐️大家好&#xff0c;我是编程导航的小编 Made 。今天安利一个强大的开源机器学习平台—TensorFlow。TensorFlow 是一个…

那些读了硕士博士的人,最不想让你知道的是什么?

全世界只有3.14 % 的人关注了青少年数学之旅在这个资讯丰富且易获取的时代&#xff0c;越来越多的人不愿意花时间阅读书籍&#xff0c;碎片化阅读成了主流。人们获取的东西多而杂&#xff0c;很难系统、全面。海量信息对人是冲击&#xff0c;更是诱惑。谁不想了解天下奇闻&…

超详细图解!【MySQL进阶篇】MySQL事务和锁

ACID 特性 在关系型数据库管理系统中&#xff0c;一个逻辑工作单元要成为事务&#xff0c;必须满足这 4 个特性&#xff0c;即所谓的 ACID&#xff1a; 原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&am…

这道题号称无人能解!300多年来无一人答对,却让这群人这么简单就解出来了?...

全世界只有3.14 % 的人关注了青少年数学之旅最近&#xff0c;一条新闻引起了超模君的注意&#xff1a;“三体问题”或有解了&#xff01;这个蔑视了人类300多年的老顽固&#xff0c;真的要被彻底解决了吗&#xff1f;三体问题到底是什么&#xff1f;三体问题是说&#xff1a;三…