快捷搜索:

php设计模式介绍之伪对象模式

面向工具的编程之以是富厚多彩,部分是因为工具间的互相联系与感化。一个单一的工具就能封装一 个繁杂的子系统,使那些很繁杂的操作能够经由过程一些措施的调用而简化。(无所不在的数据库连接便是 这样的一个工具实例。)

然而常常有这样的环境,工具间的交互性是如斯繁杂以至于我们不得 不面对类似“先有鸡照样先有蛋”这样伤脑子的问题:若何创建并测试这样一个工具,他要 么依附于很多已创建的工具,要么依附于其他一些难以意识到的环境,如全部数据库的创建和测试。

问题

若何分隔并测试一个与其他工具和资本有关的代码段?又若何再创建一个或多个对 象、法度榜样来验证你的代码能正常运行?

办理规划

当用situ(或在一个仿真的法度榜样情况 中)测试一个工具价值不菲或艰苦重重时,就可用伪工具来模拟这个行径。伪工具有同真实工具一样的 接口,但却能供给预编译相应,能跟踪措施调用,并验证调用序次。

伪工具是测试的“特 别气力”。他们被秘密练习,渗透进目标代码,模拟并监视通信要领,回报结果。伪工具有助于查 找和打消法度榜样破绽并能支持更多正常调试情况下的“防危险”操作。

注:The ServerStub

伪工具模式是另一种测试模式ServerStub的扩展。ServerStub模式替代一个资本并返 回其措施所调用的响应值。当其介入指定序次的措施的调用时ServerStub就成了伪工具。

其并非 是一个设计模式

本章与其他章不合,由于伪工具是一个测试模式而不是设计模式。这类似于一 个附加的章节,但对它的应用确凿很值得你纳入到编码进程中。另一个不合是我们不再关注这个模式如 何编码之类的根基问题,而是强调若何在SimpleTest中应用伪工具。

本章先举一个异常简单的例 子来示范SimpleTest下伪工具的基础机制。然后向你演示若何应用伪工具赞助重构已有代码与若何测试 新的办理规划。

样本代码

伪工具是工具在测试中的一个替代品,用它测试代码加倍简便 。例如,替代一个真实的数据连接——这个真实的数据连接因为一些缘故原由而不能实际连接 ——你就可以创建一个伪工具来模拟。这意味着伪工具必要准确地回应代码中所调用的相同 的利用法度榜样接口。

让我们创建一个伪工具来替代一个简单的名为Accumulator的类,这是一个求 和的类。如下是最初的Accumulator类:

// PHP4

class Accumulator {

var $total=0;

function add($item) {

$this->total += $item;

}

function total() {

return $this->total;

}

}

这个类中add()函数先累加值 到$total变量中,再交由total()函数返回 。 一个简单的累加也可以如下面这样(下面的代码被编写为 一个函数,但它也可以写成一个类)。

function calc_total($items, &$sum) {

foreach($items as $item) {

$sum->add($item);

}

}

function calc_tax(&$amount, $rate=0.07) {

return round($amount->total() * $rate,2);

}

第一个函数calc_total()用一个累加的动作求一系列值的和。下面是简单的测试:

class MockObjectTestCase extends UnitTestCase {

function testCalcTotal() {

$sum =& new Accumulator;

calc_total(array(1,2,3), $sum);

$this- >assertEqual(6, $sum->total());

}

}

让我们关注第二个例子。假设 实现一个真实的累加动作的价值很大年夜。那么用一个简单的工具来替代它并回应相关代码便是很好的做法 了。应用SimpleTest,你可以用如下代码创建一个伪累加动作:

为了应用伪工具,具有代表性 的做法是你亲身写一个新类(并不要求顿时做)。幸运的是,SimpleTest有一种轻易的手段来实现 Mock::generate() 措施。

在上面的例子中,这种手段创建了一个名为MockAccumulator的类来响 应所有Accumulator类的措施。别的,伪累加的动作还有其他手段来操作伪工具自身的实例。例如 setReturnValue()。给出一个措施名和一个值,

setReturnValue()就可以改变伪工具而给出对应 措施所调用的值。是以,这条语句$amount->setReturnValue(‘total’, 200)返回200而 不论何时调用了total()措施。

一旦进行完初始化事情后,你可以通报MockAccumulator类到 calc_tax()函数来演示一个在真实的Accumulator工具空间中的动作。

假如你止步于此 ——即用一个工具来返回所调用函数的“封装”相应——你只是应用 了ServerStub模式。 用伪工具来验证措施的调用不限于此,由于它可以不限序次与次数。

下面 是一个经由过程工具来验证“数据流”的例子:

class MockObjectTestCase extends UnitTestCase {

// ...

function testCalcTax() {

$amount =& new MockAccumulator($this);

$amount->setReturnValue(‘total’,200);

$amount->expectOnce(‘total’);

$this->assertEqual(

14, calc_tax($amount));

$amount->tally();

}

}

您可能还会对下面的文章感兴趣: