php單元測試進階(7)- 核心技術 - 樁件(stub) - 構造函數注入樁件

php單元測試進階(7)- 核心技術 - 樁件(stub) - 構造函數注入樁件

本系列文章主要代碼與文字來源于《單元測試的藝術》,原作者:Roy Osherove。譯者:金迎。

本系列文章根據php的語法與使用習慣做了改編。所有代碼在本機測試通過。如轉載請注明出處。

源代碼

(1)t2\application\index\controller下根據測試需要(實際是解耦,讓程序更加結構清晰)提取的接口
IExtensionManager.php

<?php
namespace app\index\controller;

/**
 * 文件名是否有效接口
 * 源代碼中的文件管理器類會實現,一個樁件也會實現
 * 接口的存在,讓所有代碼的含義更加清晰,穩定。
 */
interface  IExtensionManager
{
    /**
     * 判斷文件名是否有效
     * @param string $filename
     * @return boolean
     */
    public function isValid($filename);
}

(2)t2\application\index\controller下文件管理器類,實現了上面的接口,但是實際被排除在單元測試之外,不測它。應該使用集成測試來測試此類。
FileExtensionManager.php

<?php
namespace app\index\controller;

/**
 * 文件管理器類
 *
 */
class FileExtensionManager implements IExtensionManager
{
    /**
     * 根據某個配置文件的內容判斷文件名是否有效
     * @param string $filename
     */
    public function isValid($filename)
    {
        // 會使用file_get_contents函數讀取某個文件的內容
        // 這里為了簡略不寫,因為不是重點。
        return true;
    }
}

(3)t2\application\index\controller下被測類,日志分析器。使用了構造方法注入的方式來寫代碼,便于測試
LogAnalyzer.php

<?php
namespace app\index\controller;

/**
 * 日志分析器類,也是被測類
 * 
 * 注意,這是用構造方法注入的例子。
 */
class LogAnalyzer
{
    /**
     * @var IExtensionManager
     */
    private $manager;
    
    public function __construct(IExtensionManager $mgr)
    {
        $this->manager = $mgr;
    }
    
    /**
     * 判斷文件名是否有效,調用另一個類來實現
     * @param string $filename
     */
    public function isValidLogFileName($filename)
    {
        return $this->manager->isValid($filename);
    }
}

測試代碼

(4)t2\tests\index\controller\下,樁件類,用于替換文件管理器,便于測試
FakeExtensionManager.php

<?php
namespace tests\index\controller;
/**
 * 一個樁件類,用于測試日志分析器,因為日志分析會讀取文件,妨礙單元測試。
 */
class FakeExtensionManager implements \app\index\controller\IExtensionManager
{
    public $willBeValid = false;
    
    /**
     * 根據某個配置文件的內容判斷文件名是否有效
     * @param string $filename
     */
    public function isValid($filename)
    {
        return $this->willBeValid;
    }
}

(5)t2\tests\index\controller\下,最后是測試類,用構造方法注入樁件
LogAnalyzerTest.php

<?php
namespace tests\index\controller;

/**
 * 測試用的類
 */
class LogAnalyzerTest extends \think\testing\TestCase
{

    /**
     * @test
     * 使用構造器注入樁件的方法 進行測試
     * 注意,盡量使得測試的方法名稱有意義,這非常重要,便于維護測試代碼。有規律
     */
    public function isValidFileName_NameSupportedExtension_ReturnTrue()
    {
        //準備好一個返回true的樁件
        $myFakeManager = new FakeExtensionManager();
        $myFakeManager->willBeValid = true; 
        
        //開始創建被測類的對象,準備測試
        $analyzer = new \app\index\controller\LogAnalyzer($myFakeManager);
        $result = $analyzer->isValidLogFileName("short.ext");
        $this->assertTrue($result);
    }
}

打開cmd窗口,測試通過。

額外說明,本文里,源代碼的組織方式位于同一命名空間內,實際至少不應放在控制器命名空間下,本文為了簡便放一起。還有,測試代碼倒無所謂,放一起挺好

上一篇:php單元測試進階(6)- 核心技術 - 樁件(stub)
下一篇:php單元測試進階(8)- 核心技術 - 樁件(stub) - 屬性注入樁件

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容