Hatena::Groupstudyroom

文::字

2010-07-17

[] XDebug をロードするとエラーが出る 23:52  XDebug をロードするとエラーが出る - 文::字 を含むブックマーク

PHP Warning:  Xdebug MUST be loaded as a Zend extension in Unknown on line 0

php.ini で以下のように書いていたのを、

extension_dir="/path/to/extension_dir/"
extension="xdebug.so"

別途以下のように設定するとエラーが出なくなる。

zend_extension="/path/to/extension_dir/xdebug.so"

[] PEAR_PackageFileManager 23:52  PEAR_PackageFileManager - 文::字 を含むブックマーク

pear install --alldeps PEAR_PackageFileManager

上記でこけたのであらかじめ XML_Seralizer をインストールしておく。

pear install channel://pear.php.net/XML_Serializer-0.20.0

[] PEAR パッケージの package.xml 02:28  PEAR パッケージの package.xml - 文::字 を含むブックマーク

file タグの role アトリビュートの意味。

  • role="php"
    • /usr/share/php 直下におかれる
  • role="test"
    • /usr/share/php/tests/ 直下におかれる
  • role="doc"
    • /usr/share/php/doc/ 直下におかれる

という感じでいいのかな?

dir タグとか filelist タグもあるんだけど、インストールしたときにどう配置されるのかいまいちよく分からない。

2010-07-16

[] __get と __set 23:22  __get と __set - 文::字 を含むブックマーク

使いどころよく分からない。

[] 存在しないプロパティへの代入 23:22  存在しないプロパティへの代入 - 文::字 を含むブックマーク

クラス定義に宣言されていないプロパティにもどんどん値を代入できる。

いいかどうかは別として単体テストでスタブとかは作りやすいような。

<?php
class Hoge {}
$hoge = new Hoge;
$hoge->fuga = 'test 1'; 
$hoge->naha = 'test 2'; 
echo $hoge->fuga . "\n";
echo $hoge->naha . "\n";
# php nonexistent_property_test.php
test 1
test 2

DipanjanDipanjan2012/08/19 01:28I don't know who you wrote this for but you hleped a brother out.

wnevzamkwnevzamk2012/08/21 19:008u2f3M <a href="http://jqycxuqwybgk.com/">jqycxuqwybgk</a>

2010-07-14

[][] PHPUnit でのテストの命名規則 23:05  PHPUnit でのテストの命名規則 - 文::字 を含むブックマーク

ファイル名を HogeTest.php のように Test.php で終わらせないとテストケースとして認識してくれない。ディレクトリを指定してテストを一括で実行すると分かる。

たとえば以下のような構成のとき、phpunit test としても Naha.php の中のテストは実行されない。

test ディレクトリ --- HogeTest.php
                  |-- FugaTest.php
                  |-- Naha.php

[]method_exists 23:05 method_exists - 文::字 を含むブックマーク

クラス名とメソッド名を指定して存在確認する。

[]ReflectionClass#getMethods 動作確認 23:05 ReflectionClass#getMethods 動作確認 - 文::字 を含むブックマーク

ReflectionClass#getMethods はメソッドが 1 つもない場合、空の配列を返す。

  • コード
<?php
class Hoge {
}
$rc = new ReflectionClass('Hoge');
$methods = $rc->getMethods();
print($methods . "\n");
print(count($methods) . "\n");
  • 実行結果
# php reflection_class_test.php
Array
0

[] XDebug モジュール 23:05  XDebug モジュール - 文::字 を含むブックマーク

phpunit --coverage-html とかでコードカバレッジを測定するのに必要なのでインストールする。

pecl install xdebug

[] ローカルで PEAR パッケージをインストール 23:54  ローカルで PEAR パッケージをインストール - 文::字 を含むブックマーク

pear install -f SomePearPackage0.0.1.tgz

2010-07-13

[] phpize コマンド 23:12  phpize コマンド - 文::字 を含むブックマーク

ローカルで PECL モジュールビルドするときに configure ファイルを作るやつ。Debian だと php5-dev パッケージに入っている。

apt-get install php5-dev

[] クラスの存在確認 23:12  クラスの存在確認 - 文::字 を含むブックマーク

  • コード
<?php
class Hoge {}
foreach(array('Hoge', 'Fuga') as $className) {
  $existence = var_export(class_exists($className), TRUE);
  echo "$className : $existence\n";
}
  • 実行結果
# php class_exisitence_test.php
Hoge : true
Fuga : false

[] include と require の違い 23:12  include と require の違い - 文::字 を含むブックマーク

require は一回のみ読み込む、include は毎回読み込む。ループの中とかで違いが表れる。

[][] クラス自体をスタブにする 23:13  クラス自体をスタブにする - 文::字 を含むブックマーク

PHPUnit の TestCase#getMock の第 4 引数を利用できないかなと思ったけど、やっぱりダメ。

<?php

class SomeClass {
    private $obj;
    public function __construct() {
        $this->obj =  new OtherClass();
    }   
    public function doSomething() {
        $this->obj->doSomething();
    }   
}

class SomeClassTest extends PHPUnit_Framework_TestCase {
    private $obj;
    public function setUp() {
        $mockClass = $this->getMock('MockOtherClass', array('doSomething'), array(), 'OtherClass');
        $mockClass->expects($this->any())
                  ->method('doSomething')
                  ->will($this->returnValue('hello from MockOtherClass#doSomething'));
        $this->obj = new SomeClass();
    }   
    public function testDoSomething() {
        $ret = $this->obj->doSomething();
        $this->assertEquals($ret, 'hello from MockOtherClass#doSomething');
    }   
}

2010-07-12

[] php.ini の extension エントリ 00:45  php.ini の extension エントリ - 文::字 を含むブックマーク

複数行設定できる。

extension=php_fdf.dll
extension=php_filepro.dll
extension=php_gd2.dll
extension=php_java.dll
extension=php_ldap.dll
extension=php_mbstring.dll

[][] クラス自体をスタブにする 00:31  クラス自体をスタブにする - 文::字 を含むブックマーク

RSpec で Array.stub!(:size).and_return(5) って書くみたいに簡単にクラス自体をスタブ化したいんだけど、調べた限りではやり方が見つからなかった。どうやるのがいいんだろう?

eval して動的にクラス定義する方法を考えてみたけど、これだと test メソッドが 2 つ以上になったときに StubClass() 関数が 2 回以上実行されて「クラスは再定義できません」という旨のエラーになる。

runkit とか使えばいいのかな…。

<?php

/***********************************************/
/* テスト対象のクラス                          */
/***********************************************/

class SomeClass {
    private $obj;
    public function __construct() {
        $this->obj = new OtherClass(); 
    }
    public function doSomething() {
        return $this->obj->doSomething();
    }
}

/***********************************************/
/* ヘルパー関数                                */
/***********************************************/

function StubClass($className, $arrMethods=null) {
    $methods = '';
    if($arrMethods && count($arrMethods) > 0) {
        foreach($arrMethods as $name => $value) {
            $value = serialize($value);
            $methods .= "public function $name() { return unserialize('$value'); }";
        }
    }
    eval("class $className {" . $methods . "}");
    return $className;
}

/***********************************************/
/* テスト本体                                  */
/***********************************************/

class SomeClassTest extends PHPUnit_Framework_TestCase {
    private $obj;
    public function setup() {
        StubClass('OtherClass', array('doSomething' => 'something done.'));
        $this->obj = new SomeClass();
    }
    public function testDoSomething() {
        $this->assertEquals($this->obj->doSomething(), 'something done.');
    }
}

2010-07-11

[][] PHPUnit でモックオブジェクトを作るには対象クラスが予め定義されていることが必要 (?) 14:02  PHPUnit でモックオブジェクトを作るには対象クラスが予め定義されていることが必要 (?) - 文::字 を含むブックマーク

必要だったような気がするんだけど、以下の class Fuga{} をコメントアウトしても通る。

<?php
class Hoge {
    public function hogeMethod($fuga) {
        return $fuga->fugaMethod();
    }
}
//class Fuga {} // Fuga が予め定義されていることが必要?

class HogeTest extends PHPUnit_Framework_TestCase {
    public function setUp() {
        $this->hoge = new Hoge();
    }
    public function testHogeMethod() {
        $this->fuga = $this->getMock('Fuga', array('fugaMethod'));
        $this->fuga->expects($this->once())
                   ->method('fugaMethod')
                   ->will($this->returnValue('Fuga#fugaMethod called'));

        $ret = $this->hoge->hogeMethod($this->fuga);

        $this->assertEquals($ret, 'Fuga#fugaMethod called');
    }
}

[]list 関数で複数の変数に一気に代入する 13:42 list 関数で複数の変数に一気に代入する - 文::字 を含むブックマーク

<?php
list($id, $name, $url) = array(1, 'tily', 'http://studyroom.g.hatena.ne.jp/tily');
print("$id,$name,$url\n");
// -> 1,tily,http://studyroom.g.hatena.ne.jp/tily

[][] PHPUnit で同じクラスの別のメソッドをモック化する 13:34  PHPUnit で同じクラスの別のメソッドをモック化する - 文::字 を含むブックマーク

TestCase#getMock の第 2 引数にモック化してほしいメソッドを指定すると、そのメソッドだけモック化して、あとは本物のメソッドとしてインスタンス化してくれる。

<?php
class SomeClass {
    public function methodA() {
        $me = 'from method A';
        return $me . ' (' . $this->methodB() . ')';
    }
    public function methodB() {
        // not implemented yet
    }
}

class SomeClassTest extends PHPUnit_Framework_TestCase {
    private $obj;
    public function setUp() {
        $this->obj = $this->getMock('SomeClass', array('methodB'));
    }
    public function testMethodA() {
        $this->obj->expects($this->once())
                  ->method ('methodB')
                  ->will   ($this->returnValue('from mock method B'));

        $ret = $this->obj->methodA();

        $this->assertEquals($ret, 'from method A (from mock method B)');
    }
}

2010-07-08

[][]既に定義されている関数をモック化する 08:07 既に定義されている関数をモック化する - 文::字 を含むブックマーク

PHP は言語に組み込まれている基本機能のインタフェースが全然オブジェクト指向じゃないので、定義済みの関数をモック化してテストできるようにしたい。

調べてみたら PHPMockFunction というライブラリを使うとできるっぽい。使うには PECL の runkit という拡張モジュールを先にインストールしておく必要がある。詳しいインストール方法はこのへんに書いてある。

で file_get_contents とかをモックにしようとしたんだけど、「組み込み関数は再定義できません」的なエラーが出た。どうやら php.ini で runkit.internal_override を有効にする必要があるらしい。

で、上記の値を有効にしたら単体では動くようになったんだけど、PHPUnit と組み合わせて使うと Segmentation Fault が出てしまう。

以下のソースを runkit-0.9.tgz に上書きして ./configure ; make ; make install し直したらちゃんと動いた。

(make test すると半分ぐらい失敗してるけどまぁいいや。)

2009-01-17

SaeedSaeed2012/08/21 14:41Your's is the inteillgent approach to this issue.

zwxnyvkzwxnyvk2012/08/25 01:57dokbfo , [url=http://tyvujgjhjlym.com/]tyvujgjhjlym[/url], [link=http://ocruqwmnlimx.com/]ocruqwmnlimx[/link], http://cfpnknfttgxr.com/