PhpUnit, когда я использую Mock Builder для интерфейса, я получаю правильный класс - PullRequest
0 голосов
/ 06 октября 2018

У меня есть следующий класс

namespace MyApp;

use MyApp\SomeInterface;

class MyClass
{
  public function __construct(SomeInterface $s)
  {
    //Some Logic here
  }

  //Another methods implemented There
}

SomeInterface содержит следующее:

namespace MyApp

interface SomeInterface
{
  /**
  * @return SomeObject
  */
  public function someMethodToImpement();
}

И я хочу создать макет над моим тестовым классом phpunit:

namespace Tests\MyApp;

use PHPUnit\Framework\TestCase;
use MyApp\MyClass;
use MyApp\SomeInterface;

class MyClassTest extends TestCase
{
   public function someTest()
   {

     $fakeClass=new class{
          public function myFunction($arg1,$arg2)
          {
            //Dummy logic to test if called
            return $arg1+$arg2;
          }
     };

     $mockInterface=$this->createMock(SomeInterface::class)
      ->method('someMethodToImpement')
      ->will($this->returnValue($fakeClass));

     $myActualObject=new MyClass($mockInterface);
   }
}

Но как только я его запустил, я получаю сообщение об ошибке:

Tests \ MyApp \ MyClassTest :: someTest TypeError: Аргумент 1, передаваемый MyApp \ MyClass :: __ construct (), должен реализовывать интерфейс MyApp \SomeInterface, экземпляр данного PHPUnit \ Framework \ MockObject \ Builder \ InvocationMocker, вызывается в /home/vagrant/code/tests/MyApp/MyClassTest.php в строке

Знаете ли вы, почему это происходит и какна самом деле создаст макет интерфейса?

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

У меня была похожая проблема.Я исправил это, добавив эти интерфейсы как еще один mock() параметр

class Product implements PriceInterface, ProductDataInterface {
    // ...
}

Тест:

// throws error
$product = Mockery::mock(Product::class);
// works fine
$product = Mockery::mock(Product::class, 'PriceInterface, ProductDataInterface');

Ссылка на документацию

0 голосов
/ 06 октября 2018

Вместо построения макета с помощью

 $mockInterface=$this->createMock(SomeInterface::class)
      ->method('someMethodToImpement')->will($this->returnValue($fakeClass));

Разделите его на отдельные строки:

 $mockInterface=$this->createMock(SomeInterface::class);
 $mockInterface->method('someMethodToImpement')->will($this->returnValue($fakeClass));

И будет работать как шарм.

...