🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

PHPUnit

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

Q&A

解決済

1回答

1984閲覧

コントローラーのユニットテストでどうしても500エラーが返ってしまい、原因がわからない

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

PHPUnit

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

0グッド

1クリップ

投稿2019/12/02 08:59

前提・実現したいこと

クラブ退会処理のメソッドをテストしようとしているのですが、postリクエストを送ってみると500エラーが返ってきます
以下のようにログインなどしていない場合、リダイレクト処理がはしるようになっているのですがそのようになりません

そもそもメソッドの直下でvar_dump($this->request->is('post'));としても何も出なかったため、テスト対象箇所にテストコードの中で発行したリクエストが到達していないようでした

自分ではおかしい部分がどこなのか気づけませんでした
そもそもチェックの仕方はこうではないかなどありましたらご指摘いただきたいです

検証箇所のコントローラー

<?php namespace App\Controller; use Cake\Core\Configure; use App\Controller\AppController; use Facebook\Facebook; use App\Model\Table\SubscriptionStatusesTable; use App\Controller\Component\MailComponent; use Cake\Controller\ComponentRegistry; use App\Model\Table\ClubMemberStatusesTable; use Cake\Datasource\ConnectionManager; use Cake\I18n\Time; class ClubsController extends AppController { public $facebook__appID = null; public $facebook__appSecret = null; public $facebook__callbackUrl = null; public $errorRedirectUrl = null; public function initialize() { parent::initialize(); $this->loadComponent('Utility'); $this->loadComponent('OAuthFacebook'); $this->loadModel('Members'); $this->loadModel('Users'); $this->loadModel('UserInfos'); $this->loadModel('Subscriptions'); $this->loadModel('SubscriptionStatuses'); $this->loadModel('ClubsUsers'); $this->loadModel('ClubMemberStatuses'); $this->loadModel('MailChanges'); $this->loadModel('Leaves'); $this->facebook__appID = Configure::read('OAuth.Facebook.appId'); $this->facebook__appSecret = Configure::read('OAuth.Facebook.appSecret'); $this->facebook__callbackUrl = Configure::read('OAuth.Facebook.callbackUrl'); $this->errorRedirectUrl = Configure::read('OAuth.Error.redirectUrl'); $this->_payjpApiSecretKey = Configure::read('Payjp.Api.secretKey'); } /** * Before filter */ public function beforeFilter(\Cake\Event\Event $event) { parent::beforeFilter($event); $this->Auth->allow(['view', 'leave', 'index']); } ・・・略 public function leave($clubId) { var_dump($this->request->is('post')); *この状態で何も反応しなかった // Check club data $club = $this->Clubs->find() ->contain(['ClubPlans']) ->where(['Clubs.id' => $clubId]) ->first(); if (empty($club)) { $this->Flash->error(__('There is no club data.')); return $this->redirect($this->referer()); } if(!$this->Auth->user()) { return $this->redirect("/authentications/login_for_leave/" . $clubId); } else { $this->request->getSession()->write('currentClub', $clubId); $this->request->getSession()->write('inquiryUrl', $club["inquiry_form_url"]); } if ($this->request->is('post')) { \Payjp\Payjp::setApiKey($this->_payjpApiSecretKey); $payjpPlanId = $club["club_plans"][0]["payjp_plan_id"]; // Check user has subscription $sub = $this->Subscriptions->find() ->where([ 'Subscriptions.club_id' => $clubId, 'Subscriptions.user_id' => $this->Auth->user('id'), 'Subscriptions.payjp_plan_id' => $payjpPlanId, 'Subscriptions.subscription_status_id <>' => SubscriptionStatusesTable::ID_PERIODIC_BILLING__CANCEL ])->first(); if (empty($sub)) { $this->Flash->error("入会情報が見つかりません。"); return $this->redirect($this->referer()); } try { $su = \Payjp\Subscription::retrieve($sub["payjp_subscription_id"]); $su->delete(); } catch (Exception $e){ $this->Flash->error("定期決済の解除に失敗しました。サポートまでお問い合わせください。"); return $this->redirect($this->referer()); } // データ更新 $subscription = $this->Subscriptions->get($sub["id"], [ 'contain' => ['Clubs.ClubOwners.Users', 'Users.UserInfos'] ] ); $subscription = $this->Users->patchEntity($subscription, [ "subscription_status_id" => SubscriptionStatusesTable::ID_PERIODIC_BILLING__CANCEL, "canceled" => date("Y-m-d H:i:s") ]); $this->Subscriptions->save($subscription); // メール送信処理 ・・・略 return $this->redirect("/Clubs/complete_leave/" . $clubId); } $this->render(sprintf('%s/leave', $clubId)); }

発生している問題・エラーメッセージ

1) App\Test\TestCase\Controller\ClubsControllerTest::testLeave Status code is not between 200 and 204 Failed asserting that 500 is equal to 204 or is less than 204.

該当のソースコード

<?php namespace App\Test\TestCase\Controller; use App\Controller\ClubsController; use Cake\Core\App; use Cake\Core\Configure; use Cake\Http\Response; use Cake\Http\ServerRequest; use Cake\TestSuite\IntegrationTestCase; use Cake\View\Exception\MissingTemplateException; class ClubsControllerTest extends IntegrationTestCase { public function setUser(){ //ログインしている状態の作成 $login = $this->session([ 'Auth' => [ 'User' => [ 'id' => 'id', ・・・略 ] ] ]); return $login; } /** * Test leave method * * @return void */ public function testLeave() { $this->setUser(); $this->post('/clubs/leave/clubid'); $this->assertResponseOk(); // $this->assertResponsezCode(302); // $this->assertResponseNotEmpty(); // $this->assertTemplate('leave'); // $this->markTestIncomplete('Not implemented yet.'); } }

試したこと

念のためテスト対象のコントローラーのbeforeFilterと、initializeをコメント会うとにしてみましたが変化はありませんでした
ブラウザで普通に操作はできるのでこのメソッドそのものに問題があるわけではないということはわかっています
テストコードの書き方に問題があるということはわかっているのですが、どうして500エラーが返ってくるのかがわかりません

通常疑うべきポイントどのような箇所があるでしょうか?

補足情報(FW/ツールのバージョンなど)

cakephp3.5 MAMP PHP7 Mysql FaceBookSDK

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

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

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

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

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

nojimage

2019/12/03 04:03

logs/cli-error.log, logs/cli-debug.log にテスト実行時のログが出ているはずです。確認してみましょう。
退会済みユーザー

退会済みユーザー

2019/12/03 07:22

apacheとcakephpのエラー ログ見てました こっちなですね、ありがとうございます 原因確認することができました 存在しないDBへアクセスしようとしてエラーになっていました config/app.phpに書かれているテスト用のDBとは別のDB(設定ファイルにも存在しない)にアクセスしようとしており、エラーになっていました どうしても上記の設定ファイルのDBを読み込めないようなので、テスト用のDB名と上記設定ファイルのDB名をエラーでアクセスできないとなっているDB名に合わせてみました 設定ファイル変更後(sh bin/cake cache clear_all)にてキャッシュクリア。apache再起動をして見ましたが同じエラーが発生し続けています 現在のテストではfixturesのファイルだけを参照できれば問題ないので、DBにアクセスしないようにしたいのですがそういったことはできないのでしょうか?
nojimage

2019/12/03 07:34

fixturesを呼び出した場合は、テストデータベースへの接続は必須になります。アクセスできないのはデータベースの権限設定が不足しているせいかもしれません。 MySQLのfooユーザーに対して、fooユーザーが全てのデータベースへのアクセス権を持たないのであれば、名前を変更したデータベースへのアクセス権を与える必要があります。
guest

回答1

0

ベストアンサー

テストされる側の、大元のコントローラーですでに存在しておらず昔一時的に利用していたテーブルをinitializeで読み込んでいました

このため通常の処理では問題なかったのですが、テストコードから処理を流した場合こけていました

投稿2019/12/06 05:04

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問