【问题标题】:PhpUnit when I use Mock Builder for Interface I get the correct classPhpUnit 当我使用 Mock Builder for Interface 时,我得到了正确的类
【发布时间】:2019-03-11 17:17:15
【问题描述】:

我有以下课程

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:传递给 MyApp\MyClass::__construct() 的参数 1 必须实现接口 MyApp\SomeInterface,给出 PHPUnit\Framework\MockObject\Builder\InvocationMocker 的实例,在 /home/vagrant/code/tests/MyApp/MyClassTest.php 中调用上线

您知道为什么会发生这种情况以及实际将如何创建模拟接口吗?

【问题讨论】:

    标签: php mocking phpunit


    【解决方案1】:

    而不是通过构造模拟

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

    将其拆分为单独的行:

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

    而且会像魅力一样工作。

    【讨论】:

    • 谢谢,这对我有用! imo,在答案中值得一提(我建议您附加它),原因是 method()will() 方法返回调用模拟程序实例,而 createMock() 返回模拟本身,实际上必须传递给 sut(sut - 被测系统)
    • 这种重新排列有何不同...?
    • 第二次已经在这里跌跌撞撞了 xD 如何再投一个赞成票?
    【解决方案2】:

    我也遇到过类似的问题。我通过将这些接口添加为另一个 mock() 参数来修复它

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

    测试:

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

    Link to documentation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 2018-01-20
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多