這是這段時間以來結合 PHPunit 文檔和大牛們的講解,想記錄下本身學習到的知識,將來參考補充,完善學到的東西php
咱們通常使用單測對公司業務裏的代碼進行測試,他會幫忙找到你的一個個小小的思考不夠全面的地方。(雖然大牛說過開發能夠先寫單測再來寫實現的代碼,然而如今的我感受離那個仍是有好多距離來着)數據庫
stub(樁件):網絡
「將對象替換爲(可選地)返回配置好的返回值的測試替身的實踐方法稱爲上樁(stubbing)」——這是官方文檔給出的上樁解釋單元測試
也許這個形容有點抽象來着,大概的表達了這麼個意思:好比說你有一個方法,依賴了數據庫查詢,當數據庫一切正常時,這個單元測試是OK的,可是當數據庫掛掉的時候,這個單測就會掛掉。這就不符合我們 學習
單測的一些意義了,單測應該是純淨的,只驗證你的邏輯這些,因此呢,咱們就須要把這些mock掉,怎麼mock呢?就是你能夠自定義一個數據庫的返回,好比剛纔說的我須要數據庫的某個字段返回1的時候,單測就能成功,測試
這時候咱們不能徹底依賴數據庫,萬一被別人改了怎麼辦?我就本身定義這個字段返回1;之後就算網絡不通,這個字段在這裏都會返回1,是一個定義死了數據,這樣就等於把數據庫查詢給mock了ui
而後就能夠開始愉悅了······················this
在這個過程當中我遇到了這些攔路虎:spa
1.如何mockcode
2.怎麼把mock的對象傳進去
解決方法呢?
1.用樁件mock 而後在指定返回(詳情見代碼呀)
2.能夠給這個被測試的類構造一個public 屬性的參數,再在construct裏面實例化這個被mock的類,再將mock傳入這個參數裏面這個參數
====前提
我想測試的是這樣一個方法:switchClothes($username) ----經過名字查詢數據庫,性別是1的,就返回褲子,是0的,就返回裙子;
<?php Class Switch{
public $server;
public function __construct() {
$this->srv=new database();
}
public function switchClothes($username){
$gender=$this->server->find("id=$username");
if($gender==0){
return "裙子";
}else{
return "褲子";
}
}
}
查詢數據庫我封裝了一個Database類裏面的: find()
====開始寫測試
首先我須要測試的是switchClothes這個類,但是在這個類裏我須要去經過實例化database這個類用select方法,查詢數據庫再來獲得我究竟是要褲子仍是裙子。因此,,真的是太麻煩了,我只是單純的想測測這個方法的邏輯好麼,萬一數據庫掛了,萬一這個username不存在,我難道還要專門去數據庫創造這樣一條數據麼,太麻煩了也不夠好。萬一須要測試包含更新數據的方法,難道還要真的修改數據麼?
stub就華麗麗降臨了。媽媽不再用擔憂我要去操做數據庫,不再擔憂接口不通神馬的了。
我能夠對這個類進行上樁。說通俗點,我以爲就是對這個類進行了一個模擬,作了一個假的database類;
如上如 A=switchClothes B=database類 D=數據庫 C=stub 的那個類
原本應該是A調用B,B查詢數據庫的.
可是C的存在就走了紅色那條線,C不會去查數據庫,C是被我掌控的,我能夠指定裏面的find()方法返回1或者0 至少在A看來它和B同樣,反正會給我返回個0或者1來的。這就等於C 將A與B,D這個體系隔絕了開來,減小了耦合;
而後,就能夠開始構造我須要的C了。
<?php use PHPUnit\Framework\TestCase; class StubTest extends TestCase { public function testStub() { // 爲database類創建樁件。 $stub = $this->getMockBuilder("database")//類名 ->setMethods(array('find')) //能夠是多個方法 ->getMock(); // 配置樁件。 $stub->method('find')//想要設置返回值的方法 ->willReturn(0);//設置返回值 $ser=new Switch();
$ser->server=$stub; //將樁件賦值給server
$ser->switchClother("1"); //調用被測試的方法
// 如今調用將返回 '裙子'。
$this->assertEquals('裙子', $stub->find()); } } ?>
這就是C了。
單測的時候,走紅色那條路就好了。
all