質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHPUnit

PHPUnitは、PHP向けのユニット・テスト向けフレームワークで、手動では手間のかかるテスト作業を自動化し、繰り返し実行することが可能です。

Q&A

解決済

2回答

4285閲覧

PHP Unitで、パーシャルモックしたメソッドを実行するとエラーになります。

th1209

総合スコア40

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

PHPUnit

PHPUnitは、PHP向けのユニット・テスト向けフレームワークで、手動では手間のかかるテスト作業を自動化し、繰り返し実行することが可能です。

0グッド

0クリップ

投稿2016/03/09 12:52

いつもお世話になっております。
PHP Unitでモックオブジェクト作成し、モックしたメソッドを呼び出すと、
PHPUnit_Framework_MockObject_BadMethodCallException:
となり、テストが失敗してしまいます。

実行環境と実際のコードを以下に添付しますので、
どなたかご教授いただけますか?

<実行環境>

  • PHP:5.5(古いですね(笑))
  • PHPUnitのversion:4.8.21(こちらも古い...)

<コード(抜粋)>
以下になります。
質問内容とは関係ありませんが、ユーザの課金情報をロギングする機能に対するテストになります。

php

1 2<?php 3 4//1.テスト対象のコードは、以下になります 5 6class SocialApiUtil{ 7 /** 8 * KPI算出用に、ユーザの課金情報をロギングする 9 */ 10 public function loggingPaymentInfoForKpi(array $paymentInfo,$logUtil) 11 { 12 //... 13 14 //ロギング用のメソッドです。以下2つを引数に取ります。 15 //1.ロギングする際のタイトル情報(課金についてのログ、ログインについてのログetc...) 16 //2.ロギングしたい変数 17 $logUtil->kpiLogger( 18 'yamada_purchase_amount', 19 array( 20 'use_paid_coin' => $paymentInfo['use_coin'], 21 'use_free_coin' => $paymentInfo['use_free_coin'] 22 )); 23 24 return true; 25 } 26} 27 28 29//2.ユニットテストのコードは、以下です 30 31class SocialApiUtilTest extends PHPUnit_Framework_TestCase{ 32 /** 33 * データプロバイダ 34 * @dataProvider loggingPaymentInfoForKpiProvider 35 */ 36 public function loggingPaymentInfoForKpiProvider() 37 { 38 39 $paymentInfo = array( 40 'use_coin' => 0, 41 'use_free_coin' => 100, 42 ); 43 44 //ここで、ロギング用オブジェクトのモックを作ります。 45 //with($this->anything())としているので、上手くいくように思えるのですが、 46 //呼び出すとPHPUnit_Framework_MockObject_BadMethodCallException が発生します... 47 $logUtil = $this->getMockBuilder('LogUtil')->disableOriginalConstructor()->getMock(); 48 $logUtil->expects($this->any())->method('kpiLogger')->with($this->anything())->will($this->returnValue(true)); 49 50 return array( 51 '正常ケース' => array($paymentInfo,$logUtil,true), 52 '引数が不正' => array(array(),$logUtil,false), 53 ); 54 } 55 56 /** 57 * 課金情報のロギングのテスト 58 * @dataProvider loggingPaymentInfoForKpiProvider 59 */ 60 public function testLoggingPaymentInfoForKpiProvider($paymentInfo,$logUtil,$expectedRet) 61 { 62 $actualRet = $this->apiUtil->loggingPaymentInfoForKpi($paymentInfo,$logUtil); 63 $this->assertSame($expectedRet ,$actualRet); 64 } 65}

以上になります。PHPUnit使ってると、色々苦労すること多いですね^^;
mockeryが使いやすいと聞いたので、ちょっと試してみようかなーと思ってます。

それでは、ご回答よろしくお願いします!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

LogUtilクラスが見えてないのではないでしょうか。必要なファイルをrequire_onceとかしてみてください。モックを作るときに元のクラス定義をreflectionで参照していろいろ用意するのですが、指定された名前のクラスが存在しないときはメソッドのない空のクラスを仮に定義するようになっていますので上記のようなことになると思われます。

投稿2016/03/10 01:44

crhg

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

th1209

2016/03/10 04:08

crhgさん ご回答いただきありがとうございます。 こちら、Test側の処理でLogUtilクラスのメソッドを読んでみたところ、 うまく呼び出せました。なので、Test側から対象クラスが見えていないということは無さそうです。 ngyukiさんにご回答いただいた、 メソッドがstaticであるのが原因だったようです。 PHP Unitでは対処できないので、 別の方法で何とかしてみようかなと思います。 ご回答いただき、ありがとうございました!
guest

0

ベストアンサー

LogUtil::kpiLogger が static メソッドなのではないでしょうか?

static メソッドをモックして呼ぶと PHPUnit_Framework_MockObject_BadMethodCallException になります。

php

1<?php 2class Hoge 3{ 4 public static function func($val) {} 5} 6 7class HogeTest extends PHPUnit_Framework_TestCase 8{ 9 public function test() 10 { 11 $obj = $this->getMockBuilder(Hoge::class)->getMock(); 12 $obj->expects($this->any())->method('func')->with($this->anything())->will($this->returnValue(true)); 13 $this->assertTrue($obj->func(123)); 14 } 15}
1) HogeTest::test PHPUnit_Framework_MockObject_BadMethodCallException:

少し古い PHPUnit だと PHPUnit_Framework_MockObject_BadMethodCallException にはならないのですが、その場合でも expects ではモックにできません。
かわりに staticExpects を使うことが出来たのですが、最近の PHPUnit には staticExpects はありません。

http://qiita.com/ngyuki/items/ca43aaa1a728f48c8cde

投稿2016/03/09 13:22

編集2016/03/10 04:10
ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

th1209

2016/03/10 04:07

ngyukiさん ご回答頂きありがとうございます。 ご指摘いただいた通り、staticなメソッドでした...! PHP Unitではstaticメソッドのモックができないはずなので、 (確か、数年前に機能廃止している) 別の方法を取るよう検討してみます。 ご回答いただき、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問