在 phpunit 中,是否有类似于 onconsecutivecalls 的方法在“with”内部使用?方法?

发布于 2024-10-24 03:15:37 字数 475 浏览 4 评论 0原文

使用 PHPUnit,我正在嘲笑 pdo,但我正在尝试找到一种方法来准备多个数据库查询语句。

$pdo = $this->getPdoMock();
$stmt = $this->getPdoStatementMock($pdo);

$pdo->expects($this->any())
    ->method('prepare')
    ->with($this->equalTo($title_query))
    ->will($this->returnValue($stmt));

$title_stmt = $pdo->prepare($title_query);
$desc_stmt = $pdo->prepare($desc_query);

我想为“with”方法传递类似于 onConsecutiveCalls 的内容,这样我就可以准备多个语句,如上所示。 你会怎样做呢?

Using PHPUnit, I'm mocking the pdo, but I'm trying to find a way to prepare more than one database query statement.

$pdo = $this->getPdoMock();
$stmt = $this->getPdoStatementMock($pdo);

$pdo->expects($this->any())
    ->method('prepare')
    ->with($this->equalTo($title_query))
    ->will($this->returnValue($stmt));

$title_stmt = $pdo->prepare($title_query);
$desc_stmt = $pdo->prepare($desc_query);

I want to pass something similar to onConsecutiveCalls for the "with" method, so I can prepare multiple statements, as seen above.
How would you go about doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

轻拂→两袖风尘 2024-10-31 03:15:37

您可以通过使用 $this->at() 而不是 $this->any() 编写单独的期望来匹配同一方法的连续调用:

$pdo->expects($this->at(0))
    ->method('prepare')
    ->with($this->equalTo($title_query))
    ->will($this->returnValue($stmt));

$pdo->expects($this->at(1))
    ->method('prepare')
    ->with($this->equalTo($desc_query))
    ->will($this->returnValue($stmt));

$title_stmt = $pdo->prepare($title_query);
$desc_stmt = $pdo->prepare($desc_query);

You can match consecutive invocations of the same method by writing separate expectations with $this->at() instead of $this->any():

$pdo->expects($this->at(0))
    ->method('prepare')
    ->with($this->equalTo($title_query))
    ->will($this->returnValue($stmt));

$pdo->expects($this->at(1))
    ->method('prepare')
    ->with($this->equalTo($desc_query))
    ->will($this->returnValue($stmt));

$title_stmt = $pdo->prepare($title_query);
$desc_stmt = $pdo->prepare($desc_query);
煞人兵器 2024-10-31 03:15:37

PHPUnit 4.1 有一个新方法 withConsecutive()。从 Test Double 章节 中:

class FooTest extends PHPUnit_Framework_TestCase
{
    public function testFunctionCalledTwoTimesWithSpecificArguments()
    {
        $mock = $this->getMock('stdClass', array('set'));
        $mock->expects($this->exactly(2))
             ->method('set')
             ->withConsecutive(
                 array($this->equalTo('foo'), $this->greaterThan(0)),
                 array($this->equalTo('bar'), $this->greaterThan(0))
             );

        $mock->set('foo', 21);
        $mock->set('bar', 48);
    }
}

withConsecutive() 的每个参数是对于指定方法的一次调用。

PHPUnit 4.1 got a new method withConsecutive(). From the Test Double Chapter:

class FooTest extends PHPUnit_Framework_TestCase
{
    public function testFunctionCalledTwoTimesWithSpecificArguments()
    {
        $mock = $this->getMock('stdClass', array('set'));
        $mock->expects($this->exactly(2))
             ->method('set')
             ->withConsecutive(
                 array($this->equalTo('foo'), $this->greaterThan(0)),
                 array($this->equalTo('bar'), $this->greaterThan(0))
             );

        $mock->set('foo', 21);
        $mock->set('bar', 48);
    }
}

Each argument of withConsecutive() is for one call to the specified method.

空心↖ 2024-10-31 03:15:37

使用 PHPUnit 的最新版本,可接受的答案可以大大简化。

另外,虽然它与原始问题没有直接相关,但您可以通过 willReturnOnConsecutiveCalls 方法轻松地为每个方法调用提供不同返回值。

$pdo->expects($this->exactly(2))
    ->method('prepare')
    ->withConsecutive(
        $this->equalTo($title_query),
        $this->equalTo($desc_query)
    )
    ->willReturnOnConsecutiveCalls(
        $stmt, // returned on the 1st call to prepare()
        $stmt  // returned on the 2nd call to prepare()
    );

With more recent versions of PHPUnit, the accepted answer can be simplified quite a bit.

Plus, while it isn't immediately relevant to the original question, you can easily provide different return values for each method invocation via the willReturnOnConsecutiveCalls method.

$pdo->expects($this->exactly(2))
    ->method('prepare')
    ->withConsecutive(
        $this->equalTo($title_query),
        $this->equalTo($desc_query)
    )
    ->willReturnOnConsecutiveCalls(
        $stmt, // returned on the 1st call to prepare()
        $stmt  // returned on the 2nd call to prepare()
    );
油焖大侠 2024-10-31 03:15:37

我发现唯一与您要求类似的是使用“at”:

$mock->expects($this->at(0))->method // etc
$mock->expects($this->at(1))->method // etc

因此您为第一次调用(at 0)设置期望,第二次等等。

The only thing I have found resembling what you ask is using the 'at':

$mock->expects($this->at(0))->method // etc
$mock->expects($this->at(1))->method // etc

So you set expectations for the first time it is called (at 0), the second time and so on.

与风相奔跑 2024-10-31 03:15:37

有几个人注意到 at($index) 可用于调用方法的特定实例。 David H. 和 Vika 澄清说 $index 计算对该对象的所有模拟方法的所有调用。

此外,可能值得注意的是,Test Doubles 章节 PHPunit 文档对此有一个警告说明。它指出应谨慎使用 at(),因为它可能导致过度依赖于具体实现的脆弱测试。

A couple of folks have noted that at($index) can be used for specific instances of calls to a method. David H. and Vika clarified that $index counts ALL calls to ALL mocked methods of the object.

In addition, it may be worth noting that the Test Doubles Chapter of the PHPunit documentation has a warning note about this. It points out that using at() should be done with caution, since it can lead to brittle tests that depend too much on the specific implementation.

她比我温柔 2024-10-31 03:15:37

我使用 dataProvider 并需要可变数量的执行查询,我可以使用它们来填充我的提供程序,我想提供应该执行的查询数组。
withConsecutive 的问题在于它需要可变数量的数组,每个数组都是一个参数数组。

我使用以下代码解决了它,这感觉“hacky”,但正在工作:

$withConsecutiveArgs = [
    [$this->equalTo($title_query)], 
    [$this->equalTo($desc_query)],
    ..., 
    N queries
];
$withConsecutiveReturns = [
    $title_stmt, 
    $desc_stmt,
    ...,
    N returns
];

$methodMock = $pdo->expects($this->exactly(count($args))->method('prepare');
$methodMock->getMatcher()->parametersMatcher = new \PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($withConsecutiveArgs);
$methodMock->will(new \PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($withConsecutiveReturns));

$title_stmt = $pdo->prepare($title_query);
$desc_stmt = $pdo->prepare($desc_query);
...
$N_s_stmt = $pdo->prepare($N_s_query);

我希望它能够随着 PhpUnit 的未来版本正确发展(这是不确定的,因为我依赖于库的内部结构,但这就是进行单元测试的全部意义,我可能必须重构它,但生产不会因此受到影响)

I use a dataProvider and need a variable numbers of executed queries that i can use to populate my provider, i want to provide an array of the queries that should be executed.
The problem with withConsecutive is that it takes a variable number of arrays, each one an array of arguments.

I solved it using the follwing code, this feels "hacky" but is working :

$withConsecutiveArgs = [
    [$this->equalTo($title_query)], 
    [$this->equalTo($desc_query)],
    ..., 
    N queries
];
$withConsecutiveReturns = [
    $title_stmt, 
    $desc_stmt,
    ...,
    N returns
];

$methodMock = $pdo->expects($this->exactly(count($args))->method('prepare');
$methodMock->getMatcher()->parametersMatcher = new \PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($withConsecutiveArgs);
$methodMock->will(new \PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($withConsecutiveReturns));

$title_stmt = $pdo->prepare($title_query);
$desc_stmt = $pdo->prepare($desc_query);
...
$N_s_stmt = $pdo->prepare($N_s_query);

I hope it evolves correctly with future versions of PhpUnit (which is unsure, since i rely on internals of the lib, but that's the whole point of doing unit test, i may have to refactor it but production will not suffer from that)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文