系列目录

.net core集成测试之Post请求

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

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

  1. [HttpPost]
  2. public IActionResult StudentInfo(Student student)
  3. {
  4. return Content(student.Name);
  5. }

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

  1. public class Student
  2. {
  3. public string Name { get; set; }
  4. public int Age { get; set; }
  5. public byte Gender { get; set; }
  6. public string School { get; set; }
  7. }

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

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

  1. [Fact]
  2. public async Task SimplePost()
  3. {
  4. Dictionary<string, string> dict = new Dictionary<string, string>
  5. {
  6. {"name","sto"},
  7. {"age","32" },
  8. {"gender","2" },
  9. {"school","middleschool" }
  10. };
  11. var response = await _client.PostAsync("/HelloWorld/StudentInfo", new FormUrlEncodedContent(dict));
  12. response.EnsureSuccessStatusCode();
  13. var result =await response.Content.ReadAsStringAsync();
  14. Assert.Equal("sto", result);
  15. }

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

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

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

改造后的方法如下:

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

首先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注解

  1. [HttpPost]
  2. public IActionResult StudentInfo([FromBody]Student student)
  3. {
  4. return Content(student.Name);
  5. }

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

注意,很多人会想,是不是加了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. .netcore持续集成测试篇之Xunit数据驱动测试一

    系列目录 Nunit里提供了丰富的数据测试功能,虽然Xunit里提供的比较少,但是也能满足很多场景下使用了,如果数据场景非常复杂,Nunit和Xunit都是无法胜任的,有不少测试者选择自己编写一个数据 ...

  2. .netcore持续集成测试篇之开篇简介及Xunit基本使用

    系列目录 为了支持跨平台,微软为.net平台提供了.net core test sdk,这样第三方测试框架诸如Nunit,Xunit等只需要按照sdk提供的api规范进行开发便可以被dotnet cl ...

  3. .netcore持续集成测试篇之搭建内存服务器进行集成测试一

    系列目录 在web项目里,我们把每一层的代码的单元测试都通过并不代表程序能正常运行,因为这个过程缺失了http管道,很多时候我们还还需要把项目布在iis环境中或者在vs里启动iis express服务 ...

  4. .netcore持续集成测试篇之MVC测试

    前面我们讲的很多单元测试的的方法和技巧不论是在.net core和.net framework里面都是通用的,但是mvc项目里有一种比较特殊的类是Controller,首先Controller类的返回 ...

  5. .netcore持续集成测试篇之测试方法改造

    系列目录 通过前面两节讲解,我们的测试类中已经有两个测试方法了,总体上如下 public class mvc20 { private readonly HttpClient _client; publ ...

  6. .netcore持续集成测试篇之 .net core 2.1项目集成测试

    系列目录 从.net到.net core以后,微软非常努力,以每年一到两个大版本的频率在演进.net core,去年相继发布了.net core 2.1和2.2,其中2.1是长期支持版,不断的快速更新 ...

  7. .netcore持续集成测试篇之web项目验收测试

    系列目录 通过前面的单元测试,我们能够保证项目的基本模块功能逻辑是正常的,通过集成测试能够保证接口的请求是正常的.然而最终项目交付我们还需要对项目进行页面的行为进行测试,比如页面布局是否正常,按钮是否 ...

  8. .net持续集成测试篇之Nunit常见断言

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

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

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

随机推荐

  1. Effective Java第三版(一) ——用静态工厂代替构造器

    此文做为<Effective Java>系列的第一篇,所以有必要大概说下此书的特点,当然很多人可能都看过,毕竟是有着Java四大名著之一的大名在外,不过总会有萌新不了解,例如我!<E ...

  2. 小心使用strcpy函数时越界

    strcpy()函数应该是我们用的比较常用的一个函数,基本功能是将一个字符串拷贝到我指定的内存空间.但是要复制的字符串长度超过这段内存空间的话,结果可能是未知的. 比如以下的程序: #include ...

  3. NDK_OVERVIEW翻译

    Android NDK Overview Introduction: The Android NDK is a set of tools that allows Android application ...

  4. HashMap中的hash算法中的几个疑问

    HashMap中哈希算法的关键代码 //重新计算哈希值 static final int hash(Object key) { int h; return (key == null) ? 0 : (h ...

  5. CF1027D Mouse Hunt题解

    题目: 伯兰州立大学的医学部刚刚结束了招生活动.和以往一样,约80%的申请人都是女生并且她们中的大多数人将在未来4年(真希望如此)住在大学宿舍里. 宿舍楼里有nn个房间和一只老鼠!女孩们决定在一些房间 ...

  6. WMI_COM_API

    Win32_Processor // CPU 处理器 Win32_PhysicalMemory // 物理内存 Win32_Keyboard // 键盘 Win32_PointingDevice // ...

  7. 分布式Streaming Data Processing - Samza

    ​ 现在的主流的互联网应用越来越依赖streaming data来提供用户一些interesting statistics insights.以linkedin为例,最近90天有多少人看过你的link ...

  8. html+css-->background-img(背景图的设置)

    背景图:(相关验证代码请查看代码,在验证时需将当前不需要验证的代码注释掉)    1.inherit:从父元素继承属性设置    2.background-repeat:平铺(在图片大小小于元素尺寸时 ...

  9. Spark-windows安装

    Spark 目的:达到能在pycharm中测试 1.安装必要的文件: JDK AnaConda spark hadoop jdk测试:java -version Anaconda测试: 打开Anaco ...

  10. Python小故事--------Tkinter的组件描述及解析

    概念 Tkinter: 是Tk图形用户界面工具包标准(ctl)的Python接口,作为一个轻量级的跨平台图形用户界面(GUI)开发工具 frame: 屏幕上的一块矩形区域,多是用来作为容器(conta ...