gpt4 book ai didi

php - 单元测试和静态方法

转载 作者:IT王子 更新时间:2023-10-29 00:52:40 24 4
gpt4 key购买 nike

阅读并学习单元测试,试图理解 the following post这解释了静态函数调用的艰辛。

我不清楚这个问题。我一直认为静态函数是在类中舍入实用函数的好方法。比如我经常使用静态函数调用来初始化,即:

Init::loadConfig('settings.php');
Init::setErrorHandler(APP_MODE);
Init::loggingMode(APP_MODE);

// start loading app related objects ..
$app = new App();

//看完这篇文章,我现在的目标是……

$init = new Init();
$init->loadConfig('settings.php');
$init->loggingMode(APP_MODE);
// etc ...

但是,我为这门课写的几十个测试是一样的。我没有改变任何东西,它们仍然都通过了。我做错了吗?

该帖子的作者声明如下:

The basic issue with static methods is they are procedural code. I have no idea how to unit-test procedural code. Unit-testing assumes that I can instantiate a piece of my application in isolation. During the instantiation I wire the dependencies with mocks/friendlies which replace the real dependencies. With procedural programing there is nothing to “wire” since there are no objects, the code and data are separate.

现在,我从帖子中了解到静态方法会创建依赖项,但不能直观地理解为什么不能像常规方法一样轻松地测试静态方法的返回值?

我将避免使用静态方法,但我希望了解静态方法何时有用(如果有的话)。从这篇文章看来,静态方法与全局变量一样邪恶,应尽可能避免。

非常感谢您提供有关该主题的任何其他信息或链接。

最佳答案

静态方法本身并不比实例方法更难测试。当方法(静态或其他)调用其他 静态方法时,就会出现问题,因为您无法隔离被测试的方法。这是一个可能难以测试的典型示例方法:

public function findUser($id) {
Assert::validIdentifier($id);
Log::debug("Looking for user $id"); // writes to a file
Database::connect(); // needs user, password, database info and a database
return Database::query(...); // needs a user table with data
}

你想用这个方法测试什么?

  • 传递正整数以外的任何值都会抛出 InvalidIdentifierException
  • Database::query() 收到正确的标识符。
  • 找到匹配的用户时返回,找不到时返回null

这些要求很简单,但您还必须设置日志记录、连接到数据库、加载数据等。Database 类应该单独负责测试它是否可以连接和查询。 Log 类应该对日志记录执行相同的操作。 findUser() 不必处理这些,但必须处理,因为它取决于它们。

如果上述方法调用 DatabaseLog 实例上的实例方法,则测试可以传入模拟对象,其中包含特定于手头测试的脚本返回值.

function testFindUserReturnsNullWhenNotFound() {
$log = $this->getMock('Log'); // ignore all logging calls
$database = $this->getMock('Database', array('connect', 'query');
$database->expects($this->once())->method('connect');
$database->expects($this->once())->method('query')
->with('<query string>', 5)
->will($this->returnValue(null));
$dao = new UserDao($log, $database);
self::assertNull($dao->findUser(5));
}

如果 findUser() 忽略调用 connect(),为 $id 传递了错误的值(5 以上),或返回除 null 以外的任何内容。美妙之处在于不涉及数据库,使测试快速而健壮,这意味着它不会因为与测试无关的原因而失败,例如网络故障或错误的样本数据。它使您可以专注于真正重要的事情:findUser() 中包含的功能。

关于php - 单元测试和静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5961023/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com