系列目录

Web项目中,很多与用户数据交互的请求都是Post请求,想必大家都用过HttpClient构造过post请求,这里并不对HttpClient做详细介绍,只介绍一些常用的功能.并结合AutoFixture演示如何自动构造请求数据,简单手动创建Json或者Formdata的工作量,提高生产效率.

我们为上节创建的HelloWorld控制器添加一个StudentInfo方法,内容如下

       [HttpPost]
        public IActionResult StudentInfo(Student student)
        {
            return Content(student.Name);
        }

这个方法的参数是一个Student类型的对象,和早期版本mvc并没有太大差别,我们把这个Student类的代码贴出来:

 public class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public byte Gender { get; set; }
        public string School { get; set; }
    }

下面我们来构造一个对StudentInfo的请求测试方法.

如何创建测试内存服务器的方法在第8节里有讲到,这里不再讲,以下用到的都是测试服务器创建的HttpClient对象.

       [Fact]
        public async Task SimplePost()
        {
            Dictionary<string, string> dict = new Dictionary<string, string>
            {
                {"name","sto"},
                {"age","32" },
                {"gender","2" },
                {"school","middleschool" }
            };
            var response = await _client.PostAsync("/HelloWorld/StudentInfo", new FormUrlEncodedContent(dict));
            response.EnsureSuccessStatusCode();
            var result =await response.Content.ReadAsStringAsync();
            Assert.Equal("sto", result);
        }

以上代码可能大家都非常熟悉了.我们用dictionary对象构造了formdata然后做为post请求内容发送到服务端,服务端返回的是接收到的student对象的name属性,这里我们验证服务端返回的name是不是我们传过去的"sto".

然而这样做是非常耗时的,如果只写一两个测试方法还好,对成千上百个方法这样构建参数是非常繁琐和乏味的,并且如果后端对数据有限制的情况下想构造出来符合条件的数据更是麻烦,并且后端接口如果字段有修改则有可能造成测试失败.由于测试项目引用了mvc项目,因此我们可以访问到mvc项目里的这些类型,然后使用AutoFixture动态创建这些类型的实例,然后序列化为Json提交,这样会明显减少工作量并增加程序的可维护性.

AutoFixture的安装前面也提到过,并且它是支持.net core的,我们在Nuget包管理工具界面输入AutoFixture.Xunit2进行搜索,然后下载这个包即可,如果直接下载它则不用下载AutoFixture包,因为它是这个包的一个依赖,会自动安装.

改造后的方法如下:

        [Theory]
        [AutoData]
        public async Task SimplePost(Student stud)
        {
            var content = new StringContent(JsonConvert.SerializeObject(stud), Encoding.UTF8, "application/json");
            var response = await _client.PostAsync("/HelloWorld/StudentInfo", content);
            response.EnsureSuccessStatusCode();
            var result =await response.Content.ReadAsStringAsync();
             Assert.True(!string.IsNullOrEmpty(result));
        }

首先fact注解变成了Theory注解,我们知道要为测试方法添加参数需要使用Theory注解,下面添加了AutoData注解,添加以后AutoFixture就会自动为方法的参数提供值.

下面我们把stud对象序列化为json字符串,然后包装成一个stringcontent对象提交到后台,由于传入的是什么值是AutoFixture随机创建的,我们并不知道,因此不能像上面一样断言它是"sto",但是它一定是有值的,因此我们断言它不是null或者空字符串.

然而遗憾的是,以上测试却没有通过,我们看一下错误面板信息:


通过面板信息我们看到AutoFixture构建的对象Name里是有值的,然而却返回的False,我们只知道结果,其中的过程我们并不清楚,也很难直观的看到错误原因,这时候我们使用调试模式来启动测试程序

首先我们在测试方法刚进入的时候打上断点,看看传入的有没有值

进入mvc项目,在方法刚进入的地方也打上断点

下面我们对测试方法执行调试

测试方法如何调试在前面的章节中已经讲过,我们在Test Explorer面板里找到这个方法然后右键点击它的名字,在右键菜单里选择"调试单元测试",更为简单的方法是,如果一个测试方法执行失败,则在它的方法定义上会出现一个红叉


我们点击这个红叉就会出现一个浮动面板


下面有两个按钮一个是运行一个是调试,点击调试就可以进入调试模式了.

第一个断点处我们看到stud的每一个字段都是有值的

按下F5继续,进入mvc方法里的断点

我们看到这里每个字段绑定的都是默认值,也就是我们传入的值并没有绑定成功.

以上的调试是为了展示如何调试mvc测试项目,以上单步调试并不能帮助我们太多,其实是因为.net core mvc改变了以往的绑定方式,改成了webapi 2.0的绑定方式,也就是要显式的给参数加上FromBody注解方可成功绑定json数据

前面的示例我们看到formData是不需要注解就可以成功绑定的

我们改一下Mvc里的方法,增加一个frombody注解

        [HttpPost]
        public IActionResult StudentInfo([FromBody]Student student)
        {
            return Content(student.Name);
        }

我们再次运行,就能够正确绑定值了.

注意,很多人会想,是不是加了frombody注解以后即能够接收formdata类型的参数,又能接收json类型参数呢,其实答案是否定的,如果加上了frombody后再提供formdata类型参数,则会返回415不支持的格式错误.因此这里要权衡,如果是传统的mvc项目通过form提交,则不能添加frombody,当然有一些插件可以把form序列化为json,这样就可以了.

有引起朋友可能会有疑惑,我直接从浏览器发送请求或者使用postman工具就行了,干嘛这么费劲呢?这样做的意义何在呢?其实前面也说到过,使用postman或者其它工具请求一方面不利于自动化测试(当然,postman是可以做到的)另一方面这样做依赖于外部web服务器,如果有多个环境在发布更新的时候遗漏了某一个环境就会造成测试结果的不稳定,并且测试环境迁移了,测试项目也要跟着迁移,增加了维护成本.使用asp.net core自身的内存web服务器功能则完全不依赖于外部web服务器或者外部测试工具,测试时自动启动web服务器,测试完成自己销毁,极大地方便了持续测试.

.netcore持续集成测试篇之Xunit结合netcore内存服务器发送post请求的更多相关文章

  1. Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  2. Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  3. Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  4. 持续集成篇_08_Hudson持续集成服务器的使用(自动化编译、分析、打包、部署)

    持续集成篇_08_Hudson持续集成服务器的使用(自动化编译.分析.打包.部署) 1.创建任务 svn用户验证 验证通过 *****五颗*表示每分钟检查svn路径是否有变更,有变更就会重新构建,相当 ...

  5. 如何使用Jenkins进行持续集成测试

    如何使用Jenkins进行持续集成测试: 安装Java环境: 安装Jenkins:两种方式,直接运行文件:使用tomcat运行: 创建一个job,构建的时候选择 execute Windows bat ...

  6. [Asp.net 开发系列之SignalR篇]专题四:使用SignalR实现发送图片

    一.引言 在前一篇博文已经介绍了如何使用SignalR来实现聊天室的功能,在这篇文章中,将实现如何使用SignalR来实现发送图片的功能. 二.实现发送图片的思路 我还是按照之前的方式来讲述这篇文章, ...

  7. 第四篇 Replication:事务复制-订阅服务器

    本篇文章是SQL Server Replication系列的第四篇,详细内容请参考原文. 订阅服务器就是复制发布项目的所有变更将传送到的服务器.每一个发布需要至少一个订阅,但是一个发布可以有多个订阅. ...

  8. Kafka集群优化篇-调整broker的堆内存(heap)案例实操

    Kafka集群优化篇-调整broker的堆内存(heap)案例实操 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看kafka集群的broker的堆内存使用情况 1>. ...

  9. 【译】第四篇 Replication:事务复制-订阅服务器

    本篇文章是SQL Server Replication系列的第四篇,详细内容请参考原文. 订阅服务器就是复制发布项目的所有变更将传送到的服务器.每一个发布需要至少一个订阅,但是一个发布可以有多个订阅. ...

  10. NetCore持续踩坑

    坑1: vs2017 安装 .netcore2.2.2后,新建项目编译报错:.NET SDK 不支持降.NET Core2.2 设置为目标. 我以为是.netcore的sdk版本有误,于是我查看.ne ...

随机推荐

  1. SQL分页获取数据

    SQL Server分页 select * from (') t Oracle分页 SELECT * FROM (' ORDER BY MaterialNM) t

  2. oracle 自动关闭 数据库连接

    数据库启动后过一会自动断开连接(大概10分钟)    方法一.直接修改资源配置文件     分三个步骤在sqlplus环境下完成.     第一步,查询资源文件,找到CONNECT_TIME所在的pr ...

  3. 「Poetize10」封印一击

    描述 Description Nescafe由n种元素组成(编号为1~n), 第i种元素有一个封印区间[ai,bi].当封印力度E小于ai时,该元素将获得ai的封印能量:当封印力度E在ai到bi之间时 ...

  4. rsync实现文件备份同步(比如服务器镜像)

    [rsync实现网站的备份,文件的同步,不同系统的文件的同步,如果是windows的话,需要windows版本cwrsync] 一.什么是rsync rsync,remote synchronize顾 ...

  5. Composer的使用

    安装 curl -sS https://getcomposer.org/installer | php 你可以使用--install-dir选项将Composer安装到指定的目录,例如: curl - ...

  6. Django环境安装--Django从入门到精通系列教程

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...

  7. Android高级控件(三)——&#160;使用Google ZXing实现二维码的扫描和生成相关功能体系

    Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 现在的二维码可谓是烂大街了,到处都是二维码,什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...

  8. selenium 常用操作

    官方文档: https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver. ...

  9. Linux_安装

    总结:    分区-->格式化-->起一个设备文件名(逻辑分区一定从5开始)-->指定挂载点(必须是空的目录名称作为盘幅)

  10. 调用run与调用start的区别

    调用start的结果 package TestException; public class test1 { public static void main(String[] args) { // 3 ...