系列目录

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. .net持续集成测试篇之Nunit常见断言

    系列目录 Nunit测试基础之简单断言 在开始本篇之前需要补充一些内容,通过前面搭建Nunit测试环境我们知道要使一个方法成为单元测试方法首先要在此方法所在类加上TestFixture注解,并且在该方 ...

  2. .net持续集成测试篇之Nunit文件断言、字符串断言及集合断言

    使用前面讲过的方法基本上能够完成工作中的大部分任务了,然而有些功能实现起来还是比较麻烦的,比如说字符串相等性比较不区分大小写,字符串是否匹配某一正则规则,集合中的每一个(某一个)元素是否符合特定规则等 ...

  3. .net持续集成测试篇之Nunit that断言

    系列目录 that是Nunit的新语法,语义上不如简单断言,使用上也更加复杂,但是其功能更加强大. 其基本语法如下代码片段示: [Test] public void DemoTest() { bool ...

  4. .net持续集成测试篇之Nunit参数化测试

    系列目录 在进行单元测试的时候,很多时候,很多时候我们都是在单元测试方法内部提供特定的值,但是这样测试往往造成样本数不足从而导致覆盖的结果不够全面,很多时候我们更想提供来自外部的,满足条件的一组值来进 ...

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

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

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

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

  7. Jenkins+Maven+Jmeter接口自动化持续集成测试

    在上一篇<利用xsltproc转换jtl报告到html报告>中,解决了html报告的问题.本篇主要还是利用Jenkins来做持续集成测试. Jenkins需要安装的插件 Maven Int ...

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

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

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

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

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

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

随机推荐

  1. android camera 自定义开发

    1.检测是否有摄像头 /** Check if this device has a camera */ private boolean checkCameraHardware(Context cont ...

  2. 算法:poj1066 宝藏猎人问题。

    package practice; import java.util.Scanner; public class TreasureHunt { public static void main(Stri ...

  3. hdu 1041 (OO approach, private constructor to prevent instantiation, sprintf) 分类: hdoj 2015-06-17 15:57 25人阅读 评论(0) 收藏

    a problem where OO seems more natural to me, implementing a utility class not instantiable. how to p ...

  4. ARM工作模式

    ARM工作模式 学习ARM的最好的资料是ARM公司发布的资料:ARM Architecture Reference Manual.pdf 找到章节:Programmers’ Model 由文档可知:A ...

  5. Django中级篇之模板语言

    模板 一.引用变量 模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户. {{ xxx }} 二.标签 用{%  %} ...

  6. MYSQL delete性能优化!

    优化项 1. low_priority 当没有连接文章表时才进行删除操作. delete low_priority from T; 优化项 2. quick 当删除行时并不删除行的索引.如果再次插入这 ...

  7. javacript参数传递表单验证

    <!doctype html> <html> <head> <meta charset="utf-8"> <style typ ...

  8. Head First C 笔记

    嗨翻c语言 1. 入门 为什么字符从零开始编号? 字符的索引数值表示的是一个偏移量,它表示的是当前所引用的字符与第一个字符之间差多少个字符. 单双引号的区别? 单引号 一个字符,双- 字符串 字符串字 ...

  9. [Swift]LeetCode301. 删除无效的括号 | Remove Invalid Parentheses

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  10. 交互课件用什么软件------承接教育类k12/幼儿html5交互课件/动画外包

    flash交互课件能生动表达教学内容,也深受广大教育工作者的喜爱,但是目前flash课件只能在pc电脑平台上进行展示,随着移动网络的发展,Adobe宣布2020年停止对flash更新和维护,越来越多的 ...