我正在使用ORM,而我获取记录对象的方式是使用FooModel::find(1)
。 FooModel
有一个我需要模拟测试的方法。我该怎么做? (不能使用PHPUnit mock
因为这会给我一个模拟的FooModel
,它与ID 1
的记录不对应。)
示例:
class FooModel
{
// ORM model that fetches record from the DB
public function thisNeedsToBeMocked()
{
// some code here that depends on external factors so should be part of unit tests
}
}
我获取ID为1
的记录的方式是:
$fooObject = FooModel::find(1);
我需要能够在运行thisNeedsToBeMocked()
方法$fooObject
之后模仿我static
find()
。
答案 0 :(得分:0)
您遇到了经典的单元测试问题。您用于静态调用的类名是全局命名空间的一部分。这意味着您无法插入模拟。这不是你可以在这里做的魔术,要解决这个问题,你将不得不做一些代码更改。
有许多方法可以解决这个问题,并且有许多方法可以解决这个问题。我会给你一个简单的黑客解决方案。如果你想要一些不同的东西让我知道,我会编写一个例子。
我还假设您无法将ORM更改为基于静态类。
这是黑客的方法,这是一种非常糟糕的做事方式,所以你知道。在类中有一个变量,它是您需要使用的ORM类的类名。这是PHP 5.3代码。
像这样:
<?php
class Bar {
public static $ormName = 'FooModel';
public static function doStuff()
{
$className = self::$ormName;
echo $className::find(1), "\n";
}
}
然后在您的PHPUnit测试中创建一个模拟。获取它的类名,在测试主题上设置该类名。现在,您的测试对象将调用您的模拟。
有很多方法可以解决这个问题,但有些方法需要一种不直接使用类名的方法。