Malheureusement, cela n'est pas possible avec l'API de simulation par défaut de PHPUnit.
Je peux voir deux options qui peuvent vous rapprocher de quelque chose de similaire :
Utiliser -> at($x)
$context = $this->getMockBuilder('Context')
->getMock();
$context->expects($this->at(0))
->method('offsetGet')
->with('Matcher')
->will($this->returnValue(new Matcher()));
$context->expects($this->at(1))
->method('offsetGet')
->with('Logger')
->will($this->returnValue(new Logger()));
Cela fonctionnera bien, mais vous testez plus que ce que vous devriez (principalement qu'il est appelé avec le matcher en premier, ce qui est un détail d'implémentation).
Aussi, cela échouera si vous avez plus d'un appel à chacune des fonctions !
Accepter les deux paramètres et utiliser returnCallBack
C'est plus de travail mais fonctionne mieux car vous ne dépendez pas de l'ordre des appels :
Exemple de travail :
getMockBuilder('Context')
->getMock();
$context->expects($this->exactly(2))
->method('offsetGet')
->with($this->logicalOr(
$this->equalTo('Matcher'),
$this->equalTo('Logger')
))
->will($this->returnCallback(
function($param) {
var_dump(func_get_args());
// Le premier argument sera Matcher ou Logger
// donc quelque chose comme "return new $param" devrait fonctionner ici
}
));
$context->offsetGet("Matcher");
$context->offsetGet("Logger");
}
}
class Context {
public function offsetGet() { echo "org"; }
}
Cela produira la sortie suivante :
/*
$ phpunit footest.php
PHPUnit 3.5.11 par Sebastian Bergmann.
array(1) {
[0]=>
string(7) "Matcher"
}
array(1) {
[0]=>
string(6) "Logger"
}
.
Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 1 assertion)
J'ai utilisé $this->exactly(2)
dans le matcher pour montrer que cela fonctionne également en comptant les invocations. Si vous n'avez pas besoin de cela, le remplacer par $this->any()
fonctionnera bien sûr.