【问题标题】:How to stub a public setter method for a protected property in Mockery如何在 Mockery 中为受保护的属性存根公共设置方法
【发布时间】:2020-11-11 14:38:50
【问题描述】:

我想为我正在测试的同一类中的受保护属性存根公共设置方法 (setA()),但我收到此错误:

无法访问受保护的属性 Mockery_2_Foo::$a

我的目标只是对method1 进行单元测试,但该方法调用setA,所以我不确定如何刺出setA,因此它不会以任何方式干扰单元- method1 的测试结果。

class Foo {
    protected $a;
   
    public function setA($val) { 
        $this->a =  $val * 2;
    }
 
   
    public function method1($val) {  
        $this->setA($val);
        return $val * 4;
   }
   ............
}

/**
 * @coversDefaultClass Foo
 */
class FooTest {
 
    public function setUp(): void { 
        $this->foo = Mockery::mock(Foo::class) 
            ->shouldAllowMockingProtectedMethods()
            ->makePartial();  
    }
    /** 
     * @covers ::method1 
     */
    
    public function testMethod1() {
        $this->foo->shouldReceive('setA')
            ->set('a', 4);  
        $this->assertEquals(8, $this->foo->method1(2));  
    }
    ..........
}``

【问题讨论】:

    标签: unit-testing phpunit mockery


    【解决方案1】:

    Mockery 只能设置公共属性(见docs)。

    我真的不明白你想要做什么,但也许这只是因为你的简化示例。您可以创建一个匿名类来扩展 Foo 并添加所需的行为,而不是使用 Mockery:

    class FooTest extends TestCase
    {
        public function testMethod1()
        {
            $foo = new class extends Foo {
                public function setA($val)
                {
                    $this->a = 4;
                }
            };
    
            self::assertEquals(8, $foo->method1(2));
        }
    }
    

    【讨论】:

    • 我的目标只是测试method1。但是那个方法调用setA,所以我正在寻找一种方法来刺出setA,这样它就不会以任何方式影响method1的单元测试。
    • 在这种情况下,仅使用 $this->foo->shouldReceive('setA') (没有 ->set() 期望)是否也可以接受,或者您的解决方案是我应该运行此单元测试的唯一方法吗?谢谢
    • @Edville 从您给出的示例中,我想说method1 的目的是返回输入值乘以四。这就是我要测试的。我看不出有什么理由删除 setA,因为它不会以任何方式改变 method1 的结果。
    猜你喜欢
    • 2018-03-28
    • 1970-01-01
    • 2015-08-14
    • 2020-03-31
    • 2014-05-19
    • 2017-01-20
    • 1970-01-01
    • 2011-10-11
    • 2012-06-02
    相关资源
    最近更新 更多