0

I have a problem to test a Method like that

public function index(){

    if($this->request->is('get')){

        if($this->Session->check('saveConflict')){
            $this->set('conflict',true);
        }else{
            $this->set('data','test');
        }

        if($this->Session->check('full')){
            $this->set('data',$this->Model->find('all'));
        }else{
            $this->set('data','test');
        }

    }else{
        throw new BadRequestException;

    }
}

unless that method maybe doesn't make sense, here is my problem. I have to call the method "check" on the Session-Component twice. But I want that for example the first methode mock-call retruns a "false" and the second a "true".

Here's what I have

        $this->Editors->Session
        ->expects($this->once())
        ->method('check')
        ->will($this->returnValue(true));

I've tried it with the expectation "$this->at(1)" the call via order-index. But i think that isnt pretty clever because if I add a Session->check anywhere in the interpreted way though my base-method for example i have to change all those test-lines to make it work properly again.

I use CakePHP 2.4.6 and php-unit 4.1.3.

Is there any other why to do what I want to do?

Sam
  • 7,252
  • 16
  • 46
  • 65
user2140111
  • 122
  • 1
  • 9

1 Answers1

0

Use the

->will($this->onConsecutiveCalls(array('return_value1',
                                        'retur_value2',
                                        ...)));

Give the sequence of the return value in the order you want, the mocked method will return it in order.Or you can try the $this->returnCallback to do some sophisticated customize.You can find the example here How can I get PHPUnit MockObjects to return differernt values based on a parameter?.

Example
If you just want to do the unit test and cover all the path,I'll do like this:

public function testIndex()
{
  ....
  $this->Editors->Session
    ->expects($this->any())
    ->method('check')
    ->will($this->returnCallback(array($this,'sessionCallback')));
  $this->object->index();
  $this->object->index();
  .....
}
private $sessionFlag;
public function sessionCallback($value)
{
  $rtnValue = $this->sessionFlag[$value];
  $this->sessionFlag[$value] = (!$rtnValue);
  return $rtnValue;
}
Community
  • 1
  • 1
bixiaopeng
  • 383
  • 2
  • 11
  • So if i want to add anything in my class-flow which touches those mocked method i have to change the whole tests i've done. And that means i also can use This->at() index stuff. – user2140111 Jul 10 '14 at 14:14
  • Would you like to show me how you use the at()?If you change the code in the index() where invoke the check()and use the onConsecutiveCalls(), I think you have to change the code.But there is no need to change the test code in other testcases.And if you implement a perfect callback to generate the return values maybe there's also no need to change the test code I think... – bixiaopeng Jul 11 '14 at 03:16