# PHPUnit 筆記
###### tags: `ChenChe`
[windows安裝phpunit](https://jaceju-books.gitbooks.io/phpunit-in-action/content/chapters/03/1.html)
[PHPUnit官方](https://phpunit.readthedocs.io/zh_CN/latest/index.html)
[簡易設定phpunit.xml](https://yami.io/phpunit/#:~:text=PHPUnit%20%E7%9A%84%E6%AA%94%E6%A1%88-,%E8%A8%AD%E5%AE%9A%20phpunit.xml,-%E9%80%99%E5%80%8B%E6%AA%94%E6%A1%88%E6%98%AF)
---
Mock
[测试替身](https://phpunit.readthedocs.io/zh_CN/latest/test-doubles.html)
[如何使用 PHP Unit Test Mock Object](https://www.puritys.me/docs-blog/article-295-%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8-PHP-Unit-Test-Mock-Object.html)
[[PhalconPHP] Functional Test 與 PHPUnit mock 愛恨情愁](https://blog.hinablue.me/phalconphp-functional-test-yu-phpunit-mock-ai-hen-qing-chou/)
[如何在phpunit中模擬(mock)一個單例類](https://www.aiwalls.com/php%E7%B7%A8%E7%A8%8B%E6%95%99%E5%AD%B8/10/27933.html)
---
## 基礎練習
根據windows安裝phpunit,安裝phpunit之後
參考兩天搞懂的簡單 CI(一)-Unit Test
創建一個article.php跟articleTest.php
也練習到了dataProvider
article.php
```php=
<?php
class Article{
private $DB;
public function __construct()
{
$this->DB = [
[
"title"=>"hi",
"status"=>0,
],
[
"title"=>"Joea",
"status"=>1,
]
];
}
public function getArticle($id){
$article = $this->DB[$id];
return ($article) ?$article : array();
}
public function disableArticle($id){
$content = $this->DB[$id];
$content['status'] = 1;
}
}
?>
```
articleTest.php
```php=
<?php
require('article.php');
use PHPUnit\Framework\TestCase;
class ArticleTest extends TestCase{
/**
* @dataProvider articleProvider
* dataProvider is as same as testGetArticle(param1,param2,param3)
*/
public function testGetArticle($id,$title,$status){
$article = new Article();
$content = $article->getArticle($id);
$this->assertEquals($title,$content['title']);
$this->assertEquals($status,$content['status']);
}
public function testDisableArticle(){
$article = new Article();
$article->disableArticle(1);
$content = $article->getArticle(1);
$this->assertEquals(1, $content['status']);
}
public function articleProvider(){
return [
[0,'hi',0],
[1,'Joea',1]
];
}
}
?>
```
並開啟cmd,在此資料夾下phpunit .\articleTest.php

---
## 根據官方文件練習
### @depends 依賴上個function的輸出
筆者在這裡一直犯一個錯,就是@depends的生產者有使用@dataProvider,結果測試一直不過。
@datatProvider的用意 = 不用一直loop,例如
```php=
testGetArticle(0,'hi',false);
testGetArticle(1,'Joea',true);
```
會省下很多重複的程式碼。
但這裡用到的return,不會傳到使用@depends的測試案例,會變成null,看stackOverflow的人說是因為phpunit會不知道要用哪一筆
```php=
<?php
require('article.php');
use PHPUnit\Framework\TestCase;
class ArticleTest extends TestCase{
public function testDisableArticle(){
$article = new Article();
$content = $article->getArticle(1);
$content = Article::disableArticle($content);
$this->assertEquals(false, $content['status']);
return $content;
}
/**
* @depends testDisableArticle
*/
public function testEnableArticle($content){
$content = Article::enableArticle($content);
$this->assertEquals(true,$content['status']);
}
}
?>
```
article.php
```php=
<?php
class Article{
private $DB;
public function __construct()
{
$this->DB = [
[
"title"=>"hi",
"status"=>false,
],
[
"title"=>"Joea",
"status"=>true,
]
];
}
public function getArticle($id){
$article = $this->DB[$id];
return ($article) ?$article : array();
}
static public function disableArticle($content){
$content['status'] = false;
return $content;
}
static public function enableArticle($content){
$content['status'] = true;
return $content;
}
}
?>
```
### expectOutputString 對輸出進行測試
很簡單,就是比對echo print這類輸出有沒有跟預想的一樣。
```php=
articleTest.php
<?php
require('article.php');
use PHPUnit\Framework\TestCase;
class ArticleTest extends TestCase{
/**
* @dataProvider articleProvider
*/
public function testGetArticle($id,$title){
$article = new Article();
$content = $article->getArticle($id);
$this->expectOutputString("$title");
echo "$content[title]";
}
public function articleProvider(){
return [
[0,'hi'],
[1,'Joea']
];
}
}
?>
article.php
<?php
class Article{
private $DB;
public function __construct()
{
$this->DB = [
[
"title"=>"hi",
"status"=>0,
],
[
"title"=>"Joea",
"status"=>1,
]
];
}
public function getArticle($id){
$article = $this->DB[$id];
return ($article) ?$article : array();
}
public function disableArticle($id){
$content = $this->DB[$id];
$content['status'] = 1;
}
public function enableArticle($id){
$content = $this->DB[$id];
$content['status'] = 0;
}
}
?>
```
### 在console內顯示參數內容
使用fwrite(STDOUT,print_r($content,true));
不會對測試造成干擾
```php=
<?php
require('article.php');
use PHPUnit\Framework\TestCase;
class ArticleTest extends TestCase{
/**
* @dataProvider articleProvider
*/
public function testGetArticle($id,$title){
$article = new Article();
$content = $article->getArticle($id);
$this->expectOutputString("$title");
echo "$content[title]";
fwrite(STDOUT,print_r($content,true));
}
public function articleProvider(){
return [
[0,'hi'],
[1,'Joea']
];
}
}
?>