系列目錄 <https://www.cnblogs.com/tylerzhou/p/11204826.html>
.net core集成測(cè)試之Post請(qǐng)求
Web項(xiàng)目中,很多與用戶數(shù)據(jù)交互的請(qǐng)求都是Post請(qǐng)求,想必大家都用過(guò)HttpClient構(gòu)造過(guò)post請(qǐng)求,這里并不對(duì)HttpClient做詳細(xì)介紹,只介紹一些常用的功能.并結(jié)合AutoFixture演示如何自動(dòng)構(gòu)造請(qǐng)求數(shù)據(jù),簡(jiǎn)單手動(dòng)創(chuàng)建Json或者Formdata的工作量,提高生產(chǎn)效率.
我們?yōu)樯瞎?jié)創(chuàng)建的HelloWorld控制器添加一個(gè)StudentInfo方法,內(nèi)容如下
[HttpPost] public IActionResult StudentInfo(Student student) { return
Content(student.Name); }
這個(gè)方法的參數(shù)是一個(gè)Student類型的對(duì)象,和早期版本mvc并沒(méi)有太大差別,我們把這個(gè)Student類的代碼貼出來(lái):
public class Student { public string Name { get; set; } public int Age { get;
set; } public byte Gender { get; set; } public string School { get; set; } }
下面我們來(lái)構(gòu)造一個(gè)對(duì)StudentInfo的請(qǐng)求測(cè)試方法.
如何創(chuàng)建測(cè)試內(nèi)存服務(wù)器的方法在第8節(jié)里有講到,這里不再講,以下用到的都是測(cè)試服務(wù)器創(chuàng)建的HttpClient對(duì)象.
[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對(duì)象構(gòu)造了formdata然后做為post請(qǐng)求內(nèi)容發(fā)送到服務(wù)端,服務(wù)端返回的是接收到的student對(duì)象的name屬性,這里我們驗(yàn)證服務(wù)端返回的name是不是我們傳過(guò)去的"sto".
然而這樣做是非常耗時(shí)的,如果只寫一兩個(gè)測(cè)試方法還好,對(duì)成千上百個(gè)方法這樣構(gòu)建參數(shù)是非常繁瑣和乏味的,并且如果后端對(duì)數(shù)據(jù)有限制的情況下想構(gòu)造出來(lái)符合條件的數(shù)據(jù)更是麻煩,并且后端接口如果字段有修改則有可能造成測(cè)試失敗.由于測(cè)試項(xiàng)目引用了mvc項(xiàng)目,因此我們可以訪問(wèn)到mvc項(xiàng)目里的這些類型,然后使用AutoFixture動(dòng)態(tài)創(chuàng)建這些類型的實(shí)例,然后序列化為Json提交,這樣會(huì)明顯減少工作量并增加程序的可維護(hù)性.
AutoFixture的安裝前面也提到過(guò),并且它是支持.net core的,我們?cè)贜uget包管理工具界面輸入AutoFixture.Xunit2
進(jìn)行搜索,然后下載這個(gè)包即可,如果直接下載它則不用下載AutoFixture包,因?yàn)樗沁@個(gè)包的一個(gè)依賴,會(huì)自動(dòng)安裝.
改造后的方法如下:
[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)); }
首先f(wàn)act注解變成了Theory注解,我們知道要為測(cè)試方法添加參數(shù)需要使用Theory注解,下面添加了AutoData注解,添加以后AutoFixture就會(huì)自動(dòng)為方法的參數(shù)提供值.
下面我們把stud對(duì)象序列化為json字符串,然后包裝成一個(gè)stringcontent對(duì)象提交到后臺(tái),由于傳入的是什么值是AutoFixture隨機(jī)創(chuàng)建的,我們并不知道,因此不能像上面一樣斷言它是"sto",但是它一定是有值的,因此我們斷言它不是null或者空字符串.
然而遺憾的是,以上測(cè)試卻沒(méi)有通過(guò),我們看一下錯(cuò)誤面板信息:
通過(guò)面板信息我們看到AutoFixture構(gòu)建的對(duì)象Name里是有值的,然而卻返回的False,我們只知道結(jié)果,其中的過(guò)程我們并不清楚,也很難直觀的看到錯(cuò)誤原因,這時(shí)候我們使用調(diào)試模式來(lái)啟動(dòng)測(cè)試程序
首先我們?cè)跍y(cè)試方法剛進(jìn)入的時(shí)候打上斷點(diǎn),看看傳入的有沒(méi)有值
進(jìn)入mvc項(xiàng)目,在方法剛進(jìn)入的地方也打上斷點(diǎn)
下面我們對(duì)測(cè)試方法執(zhí)行調(diào)試
測(cè)試方法如何調(diào)試在前面的章節(jié)中已經(jīng)講過(guò),我們?cè)赥est
Explorer面板里找到這個(gè)方法然后右鍵點(diǎn)擊它的名字,在右鍵菜單里選擇"調(diào)試單元測(cè)試",更為簡(jiǎn)單的方法是,如果一個(gè)測(cè)試方法執(zhí)行失敗,則在它的方法定義上會(huì)出現(xiàn)一個(gè)紅叉
我們點(diǎn)擊這個(gè)紅叉就會(huì)出現(xiàn)一個(gè)浮動(dòng)面板
下面有兩個(gè)按鈕一個(gè)是運(yùn)行一個(gè)是調(diào)試,點(diǎn)擊調(diào)試就可以進(jìn)入調(diào)試模式了.
第一個(gè)斷點(diǎn)處我們看到stud的每一個(gè)字段都是有值的
按下F5繼續(xù),進(jìn)入mvc方法里的斷點(diǎn)
我們看到這里每個(gè)字段綁定的都是默認(rèn)值,也就是我們傳入的值并沒(méi)有綁定成功.
以上的調(diào)試是為了展示如何調(diào)試mvc測(cè)試項(xiàng)目,以上單步調(diào)試并不能幫助我們太多,其實(shí)是因?yàn)?net core mvc改變了以往的綁定方式,改成了webapi
2.0的綁定方式,也就是要顯式的給參數(shù)加上FromBody注解方可成功綁定json數(shù)據(jù)
前面的示例我們看到formData是不需要注解就可以成功綁定的
我們改一下Mvc里的方法,增加一個(gè)frombody注解
[HttpPost] public IActionResult StudentInfo([FromBody]Student student) {
return Content(student.Name); }
我們?cè)俅芜\(yùn)行,就能夠正確綁定值了.
注意,很多人會(huì)想,是不是加了frombody注解以后即能夠接收f(shuō)ormdata類型的參數(shù),又能接收json類型參數(shù)呢,其實(shí)答案是否定的,如果加上了frombody后再提供formdata類型參數(shù),則會(huì)返回415不支持的格式錯(cuò)誤.因此這里要權(quán)衡,如果是傳統(tǒng)的mvc項(xiàng)目通過(guò)form提交,則不能添加frombody,當(dāng)然有一些插件可以把form序列化為json,這樣就可以了.
有引起朋友可能會(huì)有疑惑,我直接從瀏覽器發(fā)送請(qǐng)求或者使用postman工具就行了,干嘛這么費(fèi)勁呢?這樣做的意義何在呢?其實(shí)前面也說(shuō)到過(guò),使用postman或者其它工具請(qǐng)求一方面不利于自動(dòng)化測(cè)試(當(dāng)然,postman是可以做到的)另一方面這樣做依賴于外部web服務(wù)器,如果有多個(gè)環(huán)境在發(fā)布更新的時(shí)候遺漏了某一個(gè)環(huán)境就會(huì)造成測(cè)試結(jié)果的不穩(wěn)定,并且測(cè)試環(huán)境遷移了,測(cè)試項(xiàng)目也要跟著遷移,增加了維護(hù)成本.使用asp.net
core自身的內(nèi)存web服務(wù)器功能則完全不依賴于外部web服務(wù)器或者外部測(cè)試工具,測(cè)試時(shí)自動(dòng)啟動(dòng)web服務(wù)器,測(cè)試完成自己銷毀,極大地方便了持續(xù)測(cè)試.
熱門工具 換一換
