【问题标题】:PHPUnit:: Mocking:: $this->once() passes. $this->at(0) failsPHPUnit:: Mocking:: $this->once() 通过。 $this->at(0) 失败
【发布时间】:2012-01-14 01:37:05
【问题描述】:

当我使用 $this->at(0) 而不是 $this->once() 时,我的测试失败了。我肯定在这里错过了一点,但我不知道是什么。有人知道那是什么吗?

/**
 * Passes
 */
public function testOne()
{
    $expected = array(
        'id' => 1,
        'name' => 'Product Name'
    );

    $mock = $this->getMock('WS');
    $mock->expects($this->once())
        ->method('getProductInfo')
        ->with($this->equalTo(1))
        ->will($this->returnValue($expected));

    $this->object->setWs($mock);

    // same as $mock->getInfo(1)
    $returned = $this->object->getWs()->getProductInfo(1);
    $this->assertEquals($expected, $returned);
}

/**
 * Fails
 */
public function testOne()
{
    $expected = array(
        'id' => 1,
        'name' => 'Product Name'
    );

    $mock = $this->getMock('WS');
    $mock->expects($this->at(0)) // all that changed
        ->method('getProductInfo')
        ->with($this->equalTo(1))
        ->will($this->returnValue($expected));

    $this->object->setWs($mock);

    // returned equals NULL
    // same as $mock->getInfo(1)
    $returned = $this->object->getWs()->getProductInfo(1);
    $this->assertEquals($expected, $returned);
}   

【问题讨论】:

    标签: php mocking phpunit


    【解决方案1】:

    我只能猜测,因为我无法查看 setWs,但唯一的区别是 ->at(0) 总是尝试匹配对模拟对象的 FIRST 函数调用,并且可能 WS 的构造函数已经调用了一些东西(举个例子)。

    如果没有可执行的测试用例,我不能说更具体的东西,也许是一般性的:

    使用 PHPUnit Mocking API 的当前功能,无需每次都使用 ->at(0)。我看到的所有使用->at() 的东西现在都可以使用->will($this->logicalOr(...)->returnCallback()->returnValueMap() 更好地表达。 See this example for at vs returnCallback

    因此,如果您没有特别需要(!)以确保方法调用的顺序正确的用例,我不会担心 :)


    基本 -> 示例,以防万一

    <?php
    
    class ClassToTest
    {
        public function willGetCalled($value) {}
    }
    
    class TestClass extends PHPUnit_Framework_TestCase
    {
        public function testWithExplicitMock()
        {   
            $mock = $this->getMock(
                'ClassToTest'
            );  
    
            $mock->expects($this->at(0))
                ->method('willGetCalled')
                ->with(5);
    
            $mock->willGetCalled(5);
        }   
    }
    

    【讨论】:

    • 嗨 edorian,谢谢您的回复。但是,ws 构造函数不会调用预期的方法,因为如果是这样,once() 将失败。我需要 ->at(0) 方法,因为我需要测试 ->at(1) 情况(相同的方法,不同的参数,不同的响应)。不管怎样,我要看看那个logicalOr。这可能会有所帮助。非常感谢!
    • @Marcelo 查看我编辑的示例链接,了解如何在不使用 ->at() 的情况下做到这一点,以及为什么这样做可能会更好。如果这不起作用,也许可以用我可以执行的东西来扩展你的问题:)
    • 我看到了您对该主题的回复。我基于我的 [尚未成为] 解决方案。这正是我需要的,但这仍然不起作用=/。我会在几分钟内过滤/粘贴我的代码。再次感谢您的帮助:)
    • 太棒了!我的班级的一个更简单的版本按预期工作。我想这意味着别的东西很乱。 =/ gist.github.com/1438292
    • 我关闭了这个话题,因为我做了一些愚蠢的事情,虽然我不知道是什么。谢谢@edorian。你真的帮了我:)
    猜你喜欢
    • 2012-09-19
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 2014-01-16
    • 1970-01-01
    相关资源
    最近更新 更多