---
# System prepended metadata

title: PHPUnit 筆記
tags: [ChenChe]

---

# 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
![](https://i.imgur.com/R0Rjf4N.png)

---
## 根據官方文件練習
### @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']
        ];
    }
}
?>