【问题标题】:PHP unit testing External static method call from different classPHP单元测试来自不同类的外部静态方法调用
【发布时间】:2015-11-06 02:23:58
【问题描述】:

我正在尝试为一个函数编写一个单元测试,该函数会立即从另一个类中加载一个对象,该类将函数的输入用作参数。我是 php 单元测试的新手,找不到任何可以解决我的特定问题的东西。我得到的一些导致无济于事的线索是使用注射器,并试图让我们反思。

我要为其编写单元测试的代码是:

public static function isUseful($item) {

  $objPromo = MyPromoCodes::Load($item->SavedSku);

  if (!is_null($objPromo)
    && ($objPromo->PromoType == MyPromoCodes::Interesting_Promo_Type)) {
    return true;
  }
  return false;
}

我试图嘲笑这个:

public function testIsUseful() {

  $injector = $this->getMockBuilder('MyPromoCodes')
    ->setMethods(array('Load'))
    ->getMock();
  $objPromo = $this->getMock('MyPromoCodes');
  $objPromo->PromoType = 'very interesting promo type';
  $injector->set($objPromo, 'MyPromoCodes');

  $lineItem1 = $this->getDBMock('LineItem');


  $this->assertTrue(MyClass::isUseful($lineItem1));

}

但是这不起作用,因为该对象没有设置方法....

不知道还有什么可以尝试的,任何帮助将不胜感激。

【问题讨论】:

标签: php unit-testing testing phpunit


【解决方案1】:

我制作了the library,它使静态类模拟成为可能:

class MyClass {

    public static $myPromoCodes = 'myPromoCodes';

    public static function isUseful($item) {

      $objPromo = self::$MyPromoCodes::Load($item->SavedSku);

      if (!is_null($objPromo)
        && ($objPromo->PromoType == MyPromoCodes::Interesting_Promo_Type)) {
        return true;
      }
      return false;
    }

}

class MyClassTest extends \PHPUnit_Framework_TestCase
{
    public function testSomething()
    {
        $myClass = Moka::stubClass('MyClass');
        $myClass::$myPromoCodes = Moka::stubClass(null, ['::Load' => (object)[ 
            'PromoType' => MyPromoCodes::Interesting_Promo_Type
        ]]);
        $this->assertTrue($myClass::isUseful((object)['SavedSku' => 'SKU']);
        $this->assertEquals([['SKU']], $myClass::$myPromoCodes->moka->report('::Load'));
    }
}

【讨论】:

    【解决方案2】:

    首先你不能用 PHPUnit 模拟静态方法。至少 4.x 和 5.x 没有。

    我建议采用这样的 DI 方法:

    class MyClass
    {
        private $promoCodesRepository;
    
        public function __construct(MyPromoCodesRepository $promoCodesRepository)
        {
            $this->promoCodesRepository = $promoCodesRepository;
        }
    
        public function isUseful(MyItem $item)
        {
            $objPromo = $this->promoCodesRepository->Load($item->SavedSku);
    
            // ...
        }
    }
    

    在这里您可以轻松地模拟 Load 方法。

    不幸的是,“静态”方法在测试期间会产生很多问题,因此最好尽可能避免它。

    【讨论】:

    • 这等于说“不要在代码中使用静态方法,因为它们很糟糕”。加油!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2011-12-24
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    相关资源
    最近更新 更多