Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何让PHPUnit MockObjects根据参数返回不同的值?_Php_Unit Testing_Mocking_Phpunit - Fatal编程技术网

如何让PHPUnit MockObjects根据参数返回不同的值?

如何让PHPUnit MockObjects根据参数返回不同的值?,php,unit-testing,mocking,phpunit,Php,Unit Testing,Mocking,Phpunit,我有一个PHPUnit mock对象,它返回“返回值”,不管它的参数是什么: // From inside a test... $mock = $this->getMock('myObject', 'methodToMock'); $mock->expects($this->any)) ->method('methodToMock') ->will($this->returnValue('return value')); 我希望能够根据传

我有一个PHPUnit mock对象,它返回
“返回值”
,不管它的参数是什么:

// From inside a test...
$mock = $this->getMock('myObject', 'methodToMock');
$mock->expects($this->any))
     ->method('methodToMock')
     ->will($this->returnValue('return value'));
我希望能够根据传递给mock方法的参数返回不同的值。我试过这样的方法:

$mock = $this->getMock('myObject', 'methodToMock');

// methodToMock('one')
$mock->expects($this->any))
     ->method('methodToMock')
     ->with($this->equalTo('one'))
     ->will($this->returnValue('method called with argument "one"'));

// methodToMock('two')
$mock->expects($this->any))
     ->method('methodToMock')
     ->with($this->equalTo('two'))
     ->will($this->returnValue('method called with argument "two"'));
但是如果mock没有使用参数
'two'
调用,这会导致PHPUnit抱怨,因此我假设
methodToMock('two')
的定义覆盖了第一个参数的定义


所以我的问题是:有没有办法让PHPUnit mock对象根据其参数返回不同的值?如果是这样,怎么办?

你是说这样的事情吗

public function TestSomeCondition($condition){
  $mockObj = $this->getMockObject();
  $mockObj->setReturnValue('yourMethod',$condition);
}

我有一个类似的问题,我也无法解决(关于PHPUnit的信息很少)。在我的例子中,我只是将每个测试分别设置为已知输入和已知输出。我意识到我不需要做一个万事通的模拟对象,我只需要一个特定测试的特定对象,因此我将测试分离出来,并可以将代码的各个方面作为一个单独的单元进行测试。我不确定这是否适用于您,但这取决于您需要测试的内容。

使用回调。e、 g.(直接来自PHPUnit文件):


在callback()中执行所需的任何处理,并根据$args返回相应的结果。

尝试:

->with($this->equalTo('one'),$this->equalTo('two))->will($this->returnValue('return value'));
我有一个类似的问题(虽然略有不同…我不需要基于参数的不同返回值,但必须进行测试以确保将两组参数传递给同一个函数)。我无意中使用了这样的东西:

$mock = $this->getMock();
$mock->expects($this->at(0))
    ->method('foo')
    ->with(...)
    ->will($this->returnValue(...));

$mock->expects($this->at(1))
    ->method('foo')
    ->with(...)
    ->will($this->returnValue(...));

这并不完美,因为它要求对foo()的2次调用的顺序是已知的,但实际上这可能并不太糟糕。

您可能希望以OOP方式进行回调:

<?php
class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnAction()
    {
        $object = $this->getMock('class_name', array('method_to_mock'));
        $object->expects($this->any())
            ->method('method_to_mock')
            ->will($this->returnCallback(array($this, 'returnCallback'));

        $object->returnAction('param1');
        // assert what param1 should return here

        $object->returnAction('param2');
        // assert what param2 should return here
    }

    public function returnCallback()
    {
        $args = func_get_args();

        // process $args[0] here and return the data you want to mock
        return 'The parameter was ' . $args[0];
    }
}
?>

来自最新phpUnit文档的
:“有时存根方法应根据预定义的参数列表返回不同的值。您可以使用创建将参数与相应返回值关联的映射。”


您还可以按如下方式返回参数:

$stub = $this->getMock(
  'SomeClass', array('doSomething')
);

$stub->expects($this->any())
     ->method('doSomething')
     ->will($this->returnArgument(0));

正如您在中所看到的,方法
returnValue($index)
允许返回给定的参数。

这并不完全是您所要求的,但在某些情况下,它可以帮助:

$mock->expects( $this->any() ) )
 ->method( 'methodToMock' )
 ->will( $this->onConsecutiveCalls( 'one', 'two' ) );

-返回按指定顺序排列的值列表,其中每个元素是以下元素的数组:

  • 首先是方法参数,最小的是返回值
例如:

->willReturnMap([
    ['firstArg', 'secondArg', 'returnValue']
])

我认为这是最简单的代码,而不是PHPUnit。但不,这不是我想要实现的。假设我有一个模拟对象,它返回给定数字的单词。我的mock方法在使用1调用时需要返回“1”,在使用2等调用时需要返回“2”。不幸的是,在我的情况下,这不起作用。mock被传递到我正在测试的方法中,测试方法使用不同的参数调用mock方法。但知道你不能解决这个问题很有趣。听起来这可能是一个PHPUnit限制。你能提供一个到文档的链接吗?我似乎无法通过“Google”找到它。注意,您可以通过传递数组来使用方法作为回调,例如
$this->returnCallback(array('MyClassTest','myCallback'))
。还可以直接向它传递闭包。这应该只在极少数情况下使用。我建议改为使用,因为它不需要在回调中编写自定义逻辑。非常感谢。另外,在PHP版本>5.4的情况下,可以使用匿名函数作为回调函数
$this->returnCallback(function(){/…})
post中的链接很旧,正确答案如下:这个答案不适用于原始问题,但它详细说明了我遇到的一个类似问题:验证是否提供了某一组参数。PHPUnit的with()接受多个参数,每个参数对应一个匹配器。通过执行
$stub=$this->getMock(
$mock->expects( $this->any() ) )
 ->method( 'methodToMock' )
 ->will( $this->onConsecutiveCalls( 'one', 'two' ) );
->willReturnMap([
    ['firstArg', 'secondArg', 'returnValue']
])
$this->BusinessMock = $this->createMock('AppBundle\Entity\Business');

    public function testBusiness()
    {
        /*
            onConcecutiveCalls : Whether you want that the Stub returns differents values when it will be called .
        */
        $this->BusinessMock ->method('getEmployees')
                                ->will($this->onConsecutiveCalls(
                                            $this->returnArgument(0),
                                            $this->returnValue('employee')                                      
                                            )
                                      );
        // first call

        $this->assertInstanceOf( //$this->returnArgument(0),
                'argument',
                $this->BusinessMock->getEmployees()
                );
       // second call


        $this->assertEquals('employee',$this->BusinessMock->getEmployees()) 
      //$this->returnValue('employee'),


    }