blogPHPでWEB+DBシステムの開発をやっています。3分38秒PHPUnitでMockオブジェクトを使うで紹介したMockオブジェクトですが、これは元クラスを継承しているわけではないので当然ながら元クラスの実装は使えません。テストする場面によっては、基本は元クラスの振る舞いをして、一部のメソッドだけMockにしたいという場合があります。そこで元クラスを継承したMockオブジェクトを作ってみます。}}?>テストケースMockオブジェクトをテストケースに書いています。Hogeクラスを継承してrequest()をオーバーライドするだけです。$result->toString();?>テストケース-返り値を設定こちらではMockHogeに変数を追加して、インスタンス変数に応じてrequest()メソッドの返り値が変わるようにしています。$result->toString();?>この方法では(Mockオブジェクト用の)コンポーネントは必要ないので手軽にMockオブジェクトを使う事ができます。元クラスの実装を生かせるのでこの例のように一部だけを変えたい場合には有用です。SimpleTestのようなMockオブジェクトとケースバイケースで使い分けるのが良いですね。詳細を見るコンピュータエンジニア向けのLifeHack本です。仕事術としてタイムマネジメントが紹介されているのですがタスクリストは全て外部記憶に追い出す(脳はより生産的な事に使う)大きなタスクは実現しやすい細かいタスクに分ける仕事とプライベートのタスクを同じように管理するなど、GTDに通じるところがあります。この本独自の自動化できるものは自動化してしまう目的に応じたドキュメントを作る日々のタスクと中長期的なタスクの折り合いタイムマネジメントと顧客対応の両立といったより実践的な内容もあります。エンジニア向けと銘打っているだけあって自動化のところではUnixコマンドが紹介されるなど、この仕事をしている人ならではのTipsが参考になりました。仕事術系の本でawkの使い方を解説しているのは見たことないです。;-)私の場合、GTDで躓いたのが「やりたいリスト」を出した後、それらを上手く分類・実践していくことでした。(実際今もリストに埋もれているままだったりしてます。)そこでこの本のタイムマネジメントの方法(日々の始めに実施するタスクを決める、優先順位を付ける等)を組み合わせると上手くいくではないかと考えています。it」の精神で早速実践ですね。3分47秒PHPUnit3がリリースされました。このバージョンにはMockがサポートされているのですが、PHPUnit3はPHP5を対象としているので残念ながらPHP4では動作しません。PHP4対応のPHPUnitでMockクラスを使う方法を探ってみました。使うのはPHPUnitと並ぶユニットテストツールのSimpleTestです。こちらはPHP4対応でMockクラスがサポートされています。これをPHPUnitと組み合わせて使ってみます。SimpleTestインストールPEARパッケージが以前はあったようなのですが、sourceforgeにはそれらしいものが見当たりませんでした。symfonyチュートリアル実践【第14~16日目】を参考に以下のコマンドでインストールしました。http://jaist.dl.sourceforge.net/sourceforge/simpletest/simpletest_1.0.0.tgzPEARパッケージが見つからない場合でもsourceforgeからソースを取得してinclude_pathで参照できる位置に配置すればOKです。PHPUnit用MockクラスSimpleTestのSimpleMockを継承してPHPUnitで使うMockクラスを記述します。}}SimpleTestOptions::setMockBaseClass('PHPUnitMock');?>テスト対象クラステスト対象のクラスはこちらです。selectCount()はテーブル名を引数に取り、テーブルのレコード数を整数で返します。擬似的に処理時間が100秒かかるようにしています。}}?>テストケースDatabaseクラスのテストケースを記述します。Mockクラスを使用することに定義した処理結果[100]がすぐに返ってきます。$result->toString();?>SimpleTestはMockクラスの他にHTTPテストも行えるなど高機能なのですが、すでにPHPUnitを使用していたので今更移行するのも億劫でした。あとはコードカバレッジも使えると良いのですが。2分22秒マジックメソッドの__get()ですが、配列を返すとforeachでNoticeが発生する場合があります。Rethans理由はforeachではread/writeモードが要求されるのに__get()ではreadモードの値が返されるためのようです。__get()がreadモードで返すのは当然のような気がしますがちと不便ですね。}?>__get()の値を別の変数に代入すれば良いようです。{?>この現象は5.2.0で発生し、5.1.6ではNoticeはでませんでした。__get()は便利で何だか使いたくなる機能ですが、配列を返す場合は注意しましょう。0分57秒strtotime()で様々な日付をunixタイムスタンプで取得できます。(2006-11-18)コメント欄からの引用です。エントリにある週の始め、終わりの日にちを取得するには以下で取得できます。"\n";?>PHPマニュアルに他の記述も載っていますのでご参考にどうぞ。3分5秒ユニットテストでプログラムで生成したデータを検証する方法です。CSVファイルを検証するテストをPHPUnitで書いてみました。$result->toString();?>ポイントは「assert失敗時のメッセージにデータを特定する項目を含めておく」くらいでしょうか。(このソースでは行数を入れていますが、DBのRecordsetを検証する時はpkeyの値を入れています。)あとはdata.csvが何万行あろうが何回テストしようがphpunitがきっちりテストしてくれます。やっている事は単純なのですが効果は高いです。他にも複雑なSQLで生成されるデータをPHPで取得して検証したり、DBに問い合わせてデータが正しいかを検証するという方法もあります。正となるデータを用意しておいてそれと比較するというのもありです。あと、ここではPHPUnitを使いましたが、データを相手にテストを行うので別にSimpleTestでも良いですし、PerlでもRubyでも何でもOKです。Javaで開発したシステムのデータをPHPで検証する、なんてこともできますね。(LL言語の利用範囲がこんなところにも;-))ロジックの自動テストも大事ですが、生成物の自動テスト(チェック)もあると心強いものです。0分51秒これ何気に困ってました。Readerで「ピンを開く」を実行しても20画面以上開けませんでした。いつのまにかピン数が15を超えるとピンするのを躊躇したり。Readerでブロックされるという件だけど、キー操作でウィンドウを開くってのはユーザーが起こしたイベントに紐付いたwindow.openではあるのだけれど、タイマーを使って順次開いたりしているので、ブラウザ側で判別するのは難しいだろうと思う。なんにせよサイトで許可していても開かないことがある、っていうのは、説明しづらくて非常に困る感じがする。(今のところabout:configやら拡張やらでdom.popup_maximumを増やすしか無いようだ。Firefox2のポップアップブロックについて調べてみたありがたや。これで気にせずにピンを付けられます。dependency?でオブジェクト同士の比較で発生するエラーについて書かれています。ポイントは循環参照と[==]での比較です。PHPでは[==]と[===]とで処理結果が異なるのは良く言われていることですが、これはオブジェクト同士でも同様です。オブジェクトの比較にあるように[==]ならオブジェクトの持つ変数同士が比較され、[===]ならオブジェクトの参照が比較されます。(Javaの==とStrings#equals()に似ていますね。)つまり循環参照しているオブジェクト同士を[==]で比較すると延々オブジェクトの変数が比較され続けてエラーが発生するというわけです。ちなみにPHP4では[==]も[===]もPHP5の[==]と同じ動作をするようです。(PHP4におけるオブジェクトの比較)呼び出し元のメソッドを使用したい場合にうっかり循環参照になっていたりするので注意が必要です。エントリではPHP5.1.6では[==]で動作していたようですが、手元の環境では5.1.6でも同じエラーが発生しました。5.2.0特有の現象というわけでは無さそうです。2分46秒cakephp.jpにあるように、1.1.10.3825のbake.phpをWindows上で使用すると上手く動作しない場合があります。この現象はcake\とは異なるディレクトリにプロジェクトを生成しようとした場合に発生するようです。Directoryが作成するプロジェクトのディレクトリなのですが、妙なパスが表示されています。D:\tmp\d:\tmp\app---------------------------------------------------------------原因はディレクトリ区切り文字を[/]に決めうちしているためです。この問題の修正パッチを作りましたのでよろしければどうぞ。{2006/11/21追記:修正パッチを取り込んで貰えました。https://trac.cakephp.org/changeset/3872他にも修正されていますし、いずれ1.1.11が出そうですね。3分57秒5.2.0の新機能にDateTimeクラスがあります。既存のdate関係の関数をクラスにまとめたもののようです。以前から思っていたのですが、日付時間データを文字列や数値で持っているのに違和感がありました。DBからデータを取得した際、DBで日付時間型(PostgreSQLならtimestamp型)のものはPHPでもそのまま扱えないかな、と思っていました。そこで自分が構築しているアプリケーションではDBのレコードをModelに格納する際に自作のDateクラスに変換しています。しておけばそのModelを使う場合は日付時間をDateクラスのメソッドで操作できます。イメージとしては以下のような感じです。YYYY/MM/DD文字列で取得$model->registerTime->getFormatString('Y/m/d');?>日付時間は色々なフォーマットに変換して表現する(YYYY/MM/DDにしたりYYYYだけ取ったり)のでクラス化した方が後は扱いやすいと思うのですが、あまりこういった話は聞かないですね。DBの日付時間型関数が充実しているだけにPHPでも、と考えてしまいます。そこで冒頭のDateTimeクラスです。いずれはPDOを使ったDBアクセスではDBの日付時間型をこのクラスに変換してくれるようになって、日付時間はDateTimeクラスで扱うというのが標準になってくれれば良いなあ、と淡い期待を抱いています。常にDateTimeクラスにされると困る人もいるでしょうから、イメージとしてはこんな感じでしょうか。PDO::PARAM_DATE);?>ひそかに注目のクラスです。2006/11/10追記:PDOとの連携を考えてみました。adhocな方法ですが、いちおうDBの日付時間型をDateTimeクラスで表現できます。