Testing 有没有办法测试方法在我的对象上触发?

Testing 有没有办法测试方法在我的对象上触发?,testing,phpunit,Testing,Phpunit,使用最新的PHPUnit,我一直在使用mock来解决我的许多需求(比如模拟GuzzleHttp\Client来测试我的api调用方法),但我遇到了一些我还没有弄清楚如何测试的问题 class Foo { public function alpha($payload): void { // If some things are found in payload then... $this->beta(); } public f

使用最新的PHPUnit,我一直在使用mock来解决我的许多需求(比如模拟GuzzleHttp\Client来测试我的api调用方法),但我遇到了一些我还没有弄清楚如何测试的问题

class Foo {
    public function alpha($payload): void
    {
        // If some things are found in payload then...
        $this->beta();
    }

    public function beta(): void
    {
        // do some stuff behind the scenes
    }
}
在上面的例子中,我想测试一下,当一种特定类型的负载被传递到Foo::alpha()中时,Foo::beta()最终会被触发。如果beta()是其他对象上的一个方法,那么我可以模拟该对象,并允许将其传递到Foo实例,并告诉它期望beta()触发一次,等等,但我不确定如何测试当它不是同一个对象时触发的触发器


这可能与PHPUnit有关吗?

简短的回答是:您可以使用部分模拟

    public function test()
    {
        $foo = $this->createPartialMock(Foo::class, ['beta']);

        $foo->expects(self::once())
            ->method('beta');

        $foo->alpha(/* payload to trigger call to beta */);
    }

较长的答案是:您可能不应该使用部分模拟。大多数情况下,这是一个迹象,表明设计出了问题。如果调用
beta
没有任何你能感觉到的效果,为什么还要验证它是否已被调用?我想你的代码是有原因的。可能您的类有一个隐式依赖项,或者它有多个职责,这些职责应该划分为单独的类。但是,如果看不到实际的代码,就很难说清楚。

我所做的是为一个类提供一些占位符方法,这些占位符方法将在特定条件下触发,其目的是最终用户将扩展此类以实现它们的实现,并只覆盖它们希望包含所述事件功能的方法(因此,为什么这些方法本身不仅仅是抽象的……我希望它们也能激发,如果用户忽略它们,它们什么也不做)。鉴于试图测试这一点的问题,我将其更改为更像您描述的方法。现在,监听器被注册并激发(并且可以被模仿)。