我在设置之后可以在PHPUnit Mock上更改方法吗?

Bri*_*say 20 php phpunit mocking

我正在尝试在setUp中创建一个模拟实例,其中包含所有重写方法的默认值,然后在几个不同的测试中,根据我正在测试的内容更改某些方法的返回值,而不必设置整个Mock .有没有办法做到这一点?

这是我尝试过的,但天真的方法不起作用.该方法仍然返回原始期望设置的值.

首先安装:

$my_mock->expects($this->any())
        ->method('one_of_many_methods')
        ->will($this->returnValue(true));
Run Code Online (Sandbox Code Playgroud)

在另一个断言之前的另一个测试:

$my_mock->expects($this->any())
        ->method('one_of_many_methods')
        ->will($this->returnValue(false));
Run Code Online (Sandbox Code Playgroud)

重复这个问题:PHPUnit Mock后来改变了期望,但没有得到回应,我认为一个新问题可能会把问题放在首位.

jst*_*ann 9

如果您多次使用相同的方法,则应使用"at"声明以及在代码中执行的正确计数.这样PHPUnit知道你的意思,并且可以正确地满足期望/断言.

以下是一个通用示例,其中多次使用方法'run':

public function testRunUsingAt()
    {
        $test = $this->getMock('Dummy');

        $test->expects($this->at(0))
            ->method('run')
            ->with('f', 'o', 'o')
            ->will($this->returnValue('first'));

        $test->expects($this->at(1))
            ->method('run')
            ->with('b', 'a', 'r')
            ->will($this->returnValue('second'));

        $test->expects($this->at(2))
            ->method('run')
            ->with('l', 'o', 'l')
            ->will($this->returnValue('third'));

        $this->assertEquals($test->run('f', 'o', 'o'), 'first');
        $this->assertEquals($test->run('b', 'a', 'r'), 'second');
        $this->assertEquals($test->run('l', 'o', 'l'), 'third');
    }
Run Code Online (Sandbox Code Playgroud)

我想这就是你要找的,但如果我误会请告诉我.

现在在模拟任何东西方面,你可以根据需要多次模拟它,但你不想用与设置中相同的名称来模拟它,否则每次使用它时你都指的是设置.如果您需要在不同的场景中测试类似的方法,那么为每个测试模拟它.您可以在设置中创建一个模拟,但是对于一个测试,在单个测试中使用不同的模拟类似项目,但不使用全局名称.

  • 我认为这应该是已接受的答案,但请注意,用于at()的索引是基于对该模拟对象的调用总数,而不是对该特定方法的调用次数.因此,如果对同一对象上的其他方法进行其他调用,则需要相应地增加索引. (7认同)

gam*_*mag 5

您可以使用 lambda 回调来执行此操作:

$one_of_many_methods_return = true;
$my_mock->expects($this->any())
        ->method('one_of_many_methods')
        ->will(
             $this->returnCallback(
                 function () use (&$one_of_many_methods_return) {
                     return $one_of_many_methods_return;
                 }
              )         
          );
$this->assertTrue($my_mock->one_of_many_methods());

$one_of_many_methods_return = false;

$this->assertFalse($my_mock->one_of_many_methods());    
Run Code Online (Sandbox Code Playgroud)

注意&use声明。


Ste*_*ott 1

我还没有尝试过这个,但是你能不能在设置中设置模拟,然后在每个测试中设置:

public function testMethodReturnsTrue
{
    $this->my_mock->will($this->returnValue(true));
    $this->assertTrue( ... );
    ...
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否有效,因为我试图在测试中设置 will() 方法,而不是在创建初始模拟时设置。