【问题标题】:How can I test this method call with PHPUnit?如何使用 PHPUnit 测试此方法调用?
【发布时间】:2012-12-14 01:30:42
【问题描述】:

要测试的代码:

// Add the activation provider argument to the factory definition
$factoryDefinition = $container->getDefinition('gremo_subscription_factory');
$factoryDefinition->addArgument(new Reference($providerId));

测试方法应该检查addArgument 方法,包括$providerId 参数。我只是在学习 PHPUnit,现在我只能打电话给$this->anything():

$container->expects($this->at(3))
    ->method('getDefinition')
    ->with('gremo_subscription_factory')
    ->will($this->returnValue($factory));

$factory->expects($this->once())
    ->method('addArgument')
    ->with($this->anything());

$this->pass->process($container);

如何检查参数类型是 Reference 类,并且(反过来)它的参数正是字符串 $providerId

【问题讨论】:

  • 新行上的那些分号看起来很糟糕
  • @llnk 同意...对这个问题有任何帮助吗?

标签: php unit-testing testing phpunit


【解决方案1】:

这相当复杂,特别是因为Reference 类没有依赖注入并且方法调用不返回任何内容。但是,我认为您可以使用argument constraints 解决它。这是我将如何执行第二个子句:

$factory->expects($this->once())
    ->method('addArgument')
    ->with($this->logicalAnd(
        $this->isInstanceOf('Reference'),
        $this->attributeEqualTo('attribute', $providerId)
    ));

logicalAnd() 中的第二项基本上只是检查创建的Reference 对象以查看是否正确分配了$providerId(我不确定$providerIdReference 构造函数中会发生什么情况,但我假设它被保存到实例变量或其他东西)。

然而,这种事情正在进入测试Reference 类的实现细节的领域,所以像这样的测试对于维护 SRP 并不是很好。通过重构代码可以更好地解决所有这些问题。一般来说,如果很难测试,可能不是测试套件的错。如果可以,请考虑先在这方面进行更改,而不是编写过于聪明的测试。

【讨论】:

  • 谢谢。不幸的是,这段代码在 Symfony 2 中很常见,没有办法避免新的Reference 调用。不知道它的构造函数会对我的值做什么,正如你所说的,这没关系,因为我必须测试我的代码。我会尝试并报告...
  • 构造函数做什么并不重要,因为你应该模拟整个事情。 $this->getMockBuilder('SomeClass') ->disableOriginalConstructor() ->getMock();
  • @rockstarz:这没有用。在这种情况下,不可能模拟 Reference 对象,因为它不是依赖注入的。
  • 实际上,我认为有一种方法可以避免对 Reference 对象进行硬编码...将其作为第二个参数传递到您的 process() 方法中。这将使整个事情变得非常容易测试。
  • @theunraveler 我不直接调用 process(),它是框架。加号不能使用attributeEqualTo,见github.com/symfony/symfony/blob/master/src/Symfony/Component/…
猜你喜欢
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2019-03-13
  • 2017-02-27
  • 1970-01-01
  • 2014-11-23
相关资源
最近更新 更多