簡單的嘲笑

介紹

PHPUnit 手冊描述了這樣的模擬 :

使用驗證期望的測試 double 替換物件的實踐,例如斷言已呼叫方法,被稱為模擬。

因此,不是儲存程式碼,而是建立一個觀察者,它不僅取代了需要沉默的程式碼,而且還觀察到現實世界中會發生特定的活動。

建立

讓我們從一個簡單的記錄器類開始,為了清楚起見,只需顯示傳送到引數中的文字(通常它會做一些對單元測試有問題的事情,比如更新資料庫):

class Logger {
    public function log($text) {
        echo $text;
    }
}

現在,讓我們建立一個 Application 類。它接受一個 Logger 物件作為 run 方法的引數, run 方法又呼叫 Logger 的 log 方法來捕獲應用程式已啟動的物件。

class Application {
  public function run(Logger $logger) {
    // some code that starts up the application

    // send out a log that the application has started
    $logger->log('Application has started');
  }
}

如果以下程式碼按寫入方式執行:

$logger = new Logger();
$app = new Application();
$app->run($logger);

然後將根據 Logger 內部的 log 方法顯示 Application has started 文字。 ****

使用模擬進行單元測試

Application 類單元測試不需要驗證 Logger 日誌方法中發生了什麼,它只需要驗證它是否被呼叫。

在 PHPUnit 測試中,建立一個觀察者來替換 Logger 類。設定該觀察器以確保僅使用引數值 Application has started 呼叫 log 方法一次。 **

然後,觀察者被髮送到 run 方法,該方法驗證實際上只呼叫了一次 log 方法並且測試用例通過了,但是沒有顯示任何文字。

class ApplicationTest extends \PHPUnit_Framework_TestCase {

  public function testThatRunLogsApplicationStart() {

    // create the observer
    $mock = $this->createMock(Logger::class);
    $mock->expects($this->once())
        ->method('log')
        ->with('Application has started');
    
    // run the application with the observer which ensures the log method was called
    $app = new Application();
    $app->run($mock);
  
  }
}