■ユーザーズフォーラム リニューアルのお知らせ
新規投稿は新ユーザーズフォーラムにお願いします。

イベントリスナーを使っているプラグインのテスト

binbin > イベントリスナーを使っているプラグインのテスト @ 2018/8/10 19:50
プラグインHoge
ここにテストコードがあって、Hoge単体ならテストが通ります。

プラグインFuga
ここにHogeに対するイベントリスナーがあって、Fugaを入れるとHogeのテストが通りません。
Fugaのdatasourceがない。というエラーが出る。
Fugaを入れてもテストが通るようにすると(Fixture追加)、Hoge単体でのテストが通らなくなります。
やっぱりFugaのdatasourceがない。

こういう場合って、どうするのが一般的なんでしょうか?

1, Test/Case/Model/HogeTest.phpの、Fixtureを切り替えできればテストが通りそうだと思ったんですが、切り替え方が分からない。
Fixture切り替えシステムを作るみたいな、果てしなく面倒そうな記事なら見つけましたが、そういうものなんでしょうか?

2, テストコードの中でイベントをdetachする
これはbaserCMSの問題じゃないだろうなーと思っていたんですが、
Baser/Event/CakeEventManager.php
の中に、detach という関数を見つけまして、これはそうなんじゃないかと思うのですが、使い方が分からない。
私の技量では何をやっているのか、読んでもよく理解できませんでした。
そして使っている箇所も見つけられない。

ggり疲れてやってまいりました。
なにかヒントでもありましたら、よろしくお願い致します。
tommy6073 > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/13 11:56
こんにちは、tommy6073です。

引用:
ここにHogeに対するイベントリスナーがあって、Fugaを入れるとHogeのテストが通りません。
Fugaのdatasourceがない。というエラーが出る。
Fugaを入れてもテストが通るようにすると(Fixture追加)、Hoge単体でのテストが通らなくなります。
やっぱりFugaのdatasourceがない。

参考にさせて頂きたいので、「datasourceがない」場合のそれぞれのエラーメッセージをそのまま貼り付けていただけないでしょうか?

引用:
Fugaを入れてもテストが通るようにすると(Fixture追加)、Hoge単体でのテストが通らなくなります。

こちらはHogeのテストにFugaのFixtureを追加するとテストが通り、
その状態でFugaプラグインを外すとHogeのテストが通らなくなるということでよいでしょうか?

個人的にはHogeがFugaに依存しないようにするため、
テストを通すためのFixtureの切り替えやイベントのdetachは行わない方がいいように思います。
依存性が高いのであれば、プラグインをまとめてひとつにしてしまうという手段も考えられるのではないでしょうか。
binbin > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/13 17:04
HogeとFuga、プラグインを両方入れてHogeのテストを動かした時に出るエラーです。
エラーのなかで、Hoge=Mcc, Fuga=MemberAdmin,それぞれこのようなプラグイン名です。
ほかにもプラグインが入っていて絡んでるんですが、FugaのFixtureを読み込めばエラーは消えます。

MISSINGTABLEEXCEPTION
Table mysite_test_member_admins for model MemberAdmin was not found in datasource test.
Test case: MccCallTest(testReserveDelete)
Stack trace:
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/Model/Model.php : 3673
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/Model/Model.php : 834
/home/kusanagi/dev_nomiss/DocumentRoot/app/Plugin/MemberAdmin/Event/MemberAdminModelEventListener.php : 37
/home/kusanagi/dev_nomiss/DocumentRoot/app/Plugin/MemberAdmin/Event/MemberAdminModelEventListener.php : 37
MemberAdminModelEventListener::pointPointUserAfterFind
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Event/CakeEventManager.php : 243
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Event/BcEventDispatcher.php : 64
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Model/BcAppModel.php : 1553
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Event/BcModelEventDispatcher.php : 71
BcModelEventDispatcher::afterFind
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Event/CakeEventManager.php : 243
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/Model/Model.php : 3358
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Model/BcAppModel.php : 1523
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Model/Datasource/DboSource.php : 619
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/Model/Model.php : 834
/home/kusanagi/dev_nomiss/DocumentRoot/app/Plugin/Point/Model/PointUser.php : 186
/home/kusanagi/dev_nomiss/DocumentRoot/app/Plugin/Point/Model/PointUser.php : 186
/home/kusanagi/dev_nomiss/DocumentRoot/app/Plugin/Mcc/Model/MccCall.php : 137
/home/kusanagi/dev_nomiss/DocumentRoot/app/Plugin/Mcc/Test/Case/Model/MccCallTest.php : 61
MccCallTest::testReserveDelete
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/Framework/TestCase.php : 988
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/Framework/TestCase.php : 838
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/Framework/TestResult.php : 648
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/Framework/TestCase.php : 783
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/TestSuite/CakeTestCase.php : 84
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/Framework/TestSuite.php : 779
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/Framework/TestSuite.php : 749
/home/kusanagi/dev_nomiss/DocumentRoot/vendors/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php : 350
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/TestSuite/CakeTestRunner.php : 67
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/TestSuite/CakeTestSuiteCommand.php : 98
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Lib/TestSuite/BaserTestSuiteDispatcher.php : 147
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php : 96
/home/kusanagi/dev_nomiss/DocumentRoot/lib/Baser/Lib/TestSuite/BaserTestSuiteDispatcher.php : 57
/home/kusanagi/dev_nomiss/DocumentRoot/app/webroot/test.php : 118


で、FugaのFixtureを読み込んだまま、Fugaを外してHogeだけにすると、それはそれでエラーになります。
さらにすいません、datasourceエラーではなかったです。

Plugin MemberAdmin could not be found.
エラー: 内部エラーが発生しました。

普通にプラグインが無い。のエラーでした。

FugaはHogeに影響を与えるためのプラグインで、組み合わせた場合と、Hoge単体でも使用できる。
というのができないかと思って、一応できたんですが、テストが通らない。という問題にあたってしまいまして、投稿させていただきました。
こういう場合のうまいやり方などありましたら、お願い致します。

引用:
テストを通すためのFixtureの切り替えやイベントのdetachは行わない方がいいように思います。

やっぱりですよね、共通ビヘイビアとかに逃して、プラグインはそれぞれ独立させるとか、考えてみたいと思います。うーん。

ryuring > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/16 12:25
こんにちは。

情報を整理しないとわけがわからないので、一旦、整理させてください。
ここまで来ると手元の環境で再現させないと解決できなさそうです。
以下の内容で間違いないでしょうか?

■ Mcc(Hoge)
・単体だとテストが通る
■ MemberAdmin(Fuga)
・Mccに対するイベントリスナーがある
・これを入れるとMccのテストが通らなくなる
(MISSINGTABLEEXCEPTION)
・Mccに、MemberAdminのFixtureを追加するとテストが通るが、Mcc単体でのテストが通らない
(Plugin MemberAdmin could not be found.)

Twitter:@ryuring
baserCMS総合サービスサイト ビーコミ

binbin > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/17 14:57
返信ありがとうございます。

その通りです。


で、これを解決するには、Fixtureを切り替えるか、イベントをデタッチするくらいしか思いつきませんでした。
やっぱり密結合だったのかなーと。
実はさらにプラグインを繋げようとしていて、これはさずがにまずいと思い、ライブラリを作って処理を逃して、
別プラグインとして独立させようと思います。


蛇足
プラグインをどんどん繋げてー、の発想が良いと思ったんですけど、きっちりやらないとnode_modulesみたいになりそうだなーと思ったり。


ryuring > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/21 15:22
こんにちは、再現できました。

やはり、Mcc プラグインは、MemberAdmin プラグインに依存すべきではないので、Mcc単独で動作する事が望ましいと思います。
依存した前提のテストは、MemberAdmin 側に書くべきですね。
やり方としては、次の2パターンしかないと思います。

- baserCMSの管理画面からプラグインをオフにする。
- イベントをデタッチする。

また、イベントのデタッチが調べて見たところやり方が面倒くさいですね。
detachの第一引数をどっから持ってくるのかという。。。

取り急ぎ、デタッチが成功したのでコードを共有しておきます。
他の簡単なやり方がありましたら教えて下さい。

$eventName = 'LayerName.PluinName.ModelName.eventName';
$listeners = CakeEventManager::instance()->listeners($eventName);
foreach($listeners as $listener) {
	if(!empty($listener['callable'])) {
		CakeEventManager::instance()->detach($listener['callable'], $eventName);
	}
}



Hoge プラグイン、Fuga モデルの、afterFindイベントの $eventName の例としては、以下のようになります。

Model.Hoge.Fuga.afterFind

Twitter:@ryuring
baserCMS総合サービスサイト ビーコミ

ryuring > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/21 15:29
追記です。

BaserTestCase を継承したテストであれば、イベントを全てリセットするメソッドが利用できるようでした。

$this->resetEvent();

Twitter:@ryuring
baserCMS総合サービスサイト ビーコミ

binbin > Re: イベントリスナーを使っているプラグインのテスト @ 2018/8/21 19:59
$this->resetEvent();


こんな便利そうなモノがあったんですねー
調査不足でした。

次回以降、機会があったら使います。
ありがとうごうざいます。






(ぐぬう)
ログイン
ユーザー名:
パスワード:


  新規登録 / パスワード紛失

検索

facebook
フォーラムで悩みが解決した場合など、よかったら「いいね!」をポチっとクリックしてください!質問の回答者や開発者の励みになります

フォーラムガイド


関連リンク

オンライン状況
26 人のユーザが現在オンラインです。 (24 人のユーザが フォーラム を参照しています。)

登録ユーザ: 0
ゲスト: 26