あなたの質問はあまり明確ではありませんが、別の状況でphpunitのモックオブジェクトを使用して別の値を返す方法を尋ねていると思いますか?
PHPUnitのモッククラスでは、カスタム関数(つまり、コールバック関数/メソッド)を指定できます。これは実質的に無制限です。
以下の例では、呼び出されるたびにストレージ内の次のURLを返すモックIUrlStorageクラスを作成しました。
public function setUp()
{
parent::setUp();
$this->fixture = new UrlDisplayer(); //change this to however you create your object
//Create a list of expected URLs for testing across all test cases
$this->expectedUrls = array(
'key1' => 'http://www.example.com/url1/'
, 'key2' => 'http://www.example.net/url2/'
, 'key3' => 'http://www.example.com/url3/'
);
}
public function testUrlDisplayerDisplaysLatestUrls {
//Init
$mockStorage = $this->getMock('IUrlStorage');
$mockStorage->expects($this->any())
->method('getUrl')
->will($this->returnCallback(array($this, 'mockgetUrl')));
reset($this->expectedUrls); //reset array before testing
//Actual Tests
$this->assertGreaterThan(0, count($this->expectedUrls));
foreach ($this->expectedUrls as $key => $expected) {
$actual = $this->fixture->displayUrl($key);
$this->assertEquals($expected, $actual);
}
}
public function mockGetUrl($name)
{
$value = current($this->expectedUrls);
next($this->expectedUrls);
//Return null instead of false when end of array is reached
return ($value === false) ? null : $value;
}
また、時には単に必要な機能を皮肉って、実際のクラスを作成する方が簡単です。これは、明確に定義された小さなインタフェースでは特に簡単です。この特定のケースで
、私が代わりに以下のクラスを使用することをお勧めします:
class MockStorage implements IUrlStorage
{
protected $urls = array();
public function addUrl($name, $url)
{
$this->urls[$name] = $url;
}
public function getUrl($name)
{
if (isset($this->urls[$name])) {
return $this->urls[$name];
}
return null;
}
}
?>
次に、あなたのユニットテストクラスにあなたは、単に以下のようなあなたのフィクスチャをインスタンス化:
public function setUp() {
$mockStorage = new MockStorage();
//Add as many expected URLs you want to test for
$mockStorage->addUrl('name1', 'http://example.com');
//etc...
$this->fixture = new UrlDisplayer($mockStorage);
}
最後に私がコメントすることができます。 :) これでテストしようとしていることを明確にできますか? IUrlStorageクラスを単体テストしますか? PHPUnitができないことを達成しようとしていることのより具体的な例を教えてください。ありがとう。 – hobodave
@hobodava:更新済み – koen