简单的嘲笑
介绍
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);
}
}