【问题标题】:Any way to test that a method fires on my object?有什么方法可以测试方法在我的对象上触发吗?
【发布时间】:2021-07-18 05:26:25
【问题描述】:

使用最新的 PHPUnit,我一直在使用模拟来解决我的许多需求(例如模拟 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 相关吗?

【问题讨论】:

    标签: testing phpunit


    【解决方案1】:

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

        public function test()
        {
            $foo = $this->createPartialMock(Foo::class, ['beta']);
    
            $foo->expects(self::once())
                ->method('beta');
    
            $foo->alpha(/* payload to trigger call to beta */);
        }
    

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

    【讨论】:

    • 我所做的是为一个类提供一些占位符方法,这些方法将在某些条件下触发,其目的是最终用户将扩展该类以实现其实现并仅覆盖他们希望的方法包括所述事件的功能(因此,为什么方法本身不仅仅是抽象......我希望它们能够触发并且如果用户忽略它们则什么也不做)。鉴于尝试对此进行测试的问题,我将其更改为更像您描述的方法。现在监听器被注册并被触发(并且可以被模拟)。
    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多