おじゃまぷよ系エンジニアメモ

アプリエンジニアからサーバーとインフラエンジニアに転身しました

phpでRedisのlRangeがPhakeで差し替えられない罠

ある日phpのRedisをPhakeでmockにしてテストしていたときにlRangeがなぜか差し替えられない状況に陥った。
ソースコードは以下のような感じ

<?php
class HogeTest extends \PHPUnit_Framework_TestCase{
    /** @var  \Redis */
    private $target;

    public function setUp(){
        $this->target = \Phake::mock(\Redis::class);
    }

    public function testHoge(){
        \Phake::when($this->target)->get("key")->thenReturn("value");
        $this->assertEquals("value", $this->target->get("key")); //OK
    }

    public function testLGet(){
        \Phake::when($this->target)->lRange("key", 0, -1)->thenReturn(["a","b"]);
        $this->assertEquals(["a","b"],$this->target->lRange("key", 0, -1) ); // NG
    }
}

functionのgetは期待通り差し替えられているのにlRangeだけはどうしてもnullが帰ってきてしまう。
phpredisを調べてみると、

github.com

このソースを見るとlRangeはlGetRangeのエイリアスとして存在しているらしい。
つまりlRangeは本来存在しないfunction…
ということでlGetRangeに置き換えてみると無事にfunctionを差し替えることが出来ました

<?php
class HogeTest extends \PHPUnit_Framework_TestCase{
    /** @var  \Redis */
    private $target;

    public function setUp(){
        $this->target = \Phake::mock(\Redis::class);
    }

    public function testLGetRange(){
        \Phake::when($this->target)->lGetRange("key", 0, -1)->thenReturn(["a","b"]);
        $this->assertEquals(["a","b"],$this->target->lGetRange("key", 0, -1) ); //OK
    }
}

phpのエクステンションでエイリアスとして存在するfunctionは置き換えられないということに気をつけて、次もしPhakeで差し替わらないfunctionあったときはエイリアスを疑おう