当前位置: 首页 > 面试题库 >

单元测试和静态方法

公羊俭
2023-03-14
问题内容

阅读并学习单元测试,尝试理解下面的文章,该文章解释了静态函数调用的困难。

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

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 ...

但是,我为此课程编写的几十个测试是相同的。我什么都没改变,他们仍然都过去了。难道我做错了什么?

该帖子的作者指出:

静态方法的基本问题是它们是过程代码。
我不知道如何对程序代码进行单元测试。单元测试假设我可以孤立地实例化我的应用程序的一部分。在实例化过程中,我将依赖关系与模拟/友好关系连接起来,以替换实际的依赖关系。使用过程编程时,由于没有对象,因此代码和数据是分开的,因此无需“连线”。

现在,我从这篇文章中了解到静态方法会创建依赖关系,但是却无法直观地理解为什么不能像常规方法那样轻松地测试静态方法的返回值?

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

任何有关该主题的其他信息或链接将不胜感激。


问题答案:

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

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(),传递$id5)的错误值或返回以外的其他值,则上述测试将失败null。优点是不涉及任何数据库,从而使测试快速而稳健,这意味着它不会因与测试无关的原因而失败,例如网络故障或错误的样本数据。它使您可以专注于真正重要的事情:中包含的功能findUser()



 类似资料:
  • 我需要junit测试一段代码,但它从不同类调用的GsonConverter是静态方法,我无法更改。我不知道如何进行,因为我不能嘲笑它,因为它是静态的。 下面是带有静态方法的类

  • 我正在为我的一个应用程序编写单元测试,作为一个很好的实践,我试图使我的类中的所有方法尽可能私有,所以我最终可能会使用大部分私有方法的类,很少使用公共方法,有时还会调用一些静态方法(我的其他类或一些文本,等等) 我想知道如何测试我试图只依赖Mockito和JUnit的所有类,因为Robolectric和Powermockito似乎扩展了单元测试中应该做什么的边界。我应该忽略所有私有和静态方法,以及偶

  • 问题内容: 嗨,我真的希望您能为我提供帮助,我感觉我已经把头发拉了好几天了。 我正在尝试为方法A编写单元测试。方法A调用静态方法B。我想模拟静态方法B。 我知道以前已经有人问过这个问题,但是我觉得Android从那时起已经成熟,并且必须有一种方法可以执行如此简单的任务,而无需重写我要测试的方法。 这是一个示例,首先是我要测试的方法: 接下来,我要模拟的静态方法: 在其他语言中,这是如此简单,但我无

  • 嗨,我真的希望你能帮助我,我感觉我的头发已经拔了好几天了。 我正在尝试为一个方法a编写单元测试。方法a调用一个静态方法B。我想模拟静态方法B。 我知道以前有人问过这个问题,但我感觉Android从那以后已经成熟了,肯定有一种方法可以做到这么简单的任务,而不用重新编写我想测试的方法。 在其他语言中这是如此容易,但我就是无法使它在Android中工作。我试过Mockito,但似乎不支持静态方法 此错误

  • 我有一个这样的方法。 > 如果我模拟记录器,是否必须将方法更改为post(字符串json,记录器记录器)?否则,如何使此模拟与该方法交互?

  • 我在一个外部包中有@Entity类,它也有静态元模型。在我的应用程序的服务类中,我使用这些元模型和EntityManager/criteria builder/criteria query来检索我的数据。这在运行应用程序时工作良好。然而,当运行单元测试时,我的元模型和它们的属性总是空的。 密码 我的应用程序服务类中的使用情况。。。 “RepositoryQueryBuilder”类只是一个实用程序