gpt4 book ai didi

php - 在 phpspec 中测试多个方法的调用

转载 作者:行者123 更新时间:2023-11-28 20:40:41 24 4
gpt4 key购买 nike

过去我总是偶然发现 phpspec 的某个问题:

假设我有一个方法调用另一个对象的多个方法

class Caller {
public function call(){
$this->receiver->method1();
...
$this->receiver->method2();
}
}

在 BDD 中,我会首先编写一个测试,以确保调用 method1

function it_calls_method1_of_receiver(Receiver $receiver){
$receiver->method1()->shouldBeCalled();
$this->call();
}

然后我将编写下一个测试以确保调用 method2

function it_calls_method2_of_receiver(Receiver $receiver){
$receiver->method2()->shouldBeCalled();
$this->call();
}

但此测试在 phpspec 中失败,因为 method1method2 之前被调用。为了满足 phpspec,我必须检查这两个方法调用。

 function it_calls_method2_of_receiver(Receiver $receiver){
$receiver->method1()->shouldBeCalled();
$receiver->method2()->shouldBeCalled();
$this->call();
}

我的问题是,它会使每个测试都膨胀。在此示例中,它只是一个额外的行,但可以想象一个方法可以构建一个具有大量 setter 的对象。我需要为每个测试编写所有 setter 。很难看出测试的目的,因为每个测试都很大而且看起来都一样。

我很确定这不是 phpspec 或 bdd 的问题,而是我的体系结构的问题。什么是更好(更可测试)的编写方式?

例如:

public function handleRequest($request, $endpoint){
$endpoint->setRequest($request);
$endpoint->validate();
$endpoint->handle();
}

我在这里验证请求是否为特定端点提供了所有必要的信息(或抛出异常),然后处理请求。我选择这种模式来将验证与端点逻辑分开。

最佳答案

Prophecy , PhpSpec 使用的模拟框架,很有主见。它遵循 mockist 方法(TDD 伦敦学院),该方法捍卫我们应该一次描述一种行为。

模拟是一种测试,因此您希望每次测试都保留一个模拟。您可以模拟所有调用,但这看起来并不优雅。推荐的方法是分离您正在测试的行为并选择该行为所需的模拟,对其余调用进行 stub 。如果您发现自己在一个测试中创建了大量的 stub ,表明对功能的嫉妒——您应该考虑将行为转移给被调用者,或者在中间添加一个人。

假设您决定继续并描述您拥有的代码,而不进行重构。如果您对第二个调用感兴趣,根据您的示例,您应该使用 willReturn 或类似方法对其他调用进行 stub 。例如。 $endpoint->setRequest(Argument::type(Request::class))->willReturn() 而不是 shouldBeCalled()

关于php - 在 phpspec 中测试多个方法的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34474097/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com