ngrok(エングロック)を用いて、Twitter DeveloperのCallbackURLを設定する

ngrokとは.使い方.などに関しては、以前記事を書きましたのでご確認ください。

今回は、Twitter DeveloperのCallbackURLを設定する方法です。

Twitter DeveloperのCallbackURL では、httpsが必須、localhostが利用不可という状況です。開発環境時に利用するのが少し手間どってしまう状況かと思います。

ただ、挙動確認のためにドメインやサーバーを準備するのも手間です…
そこで、利用するのは、ngrokです。localhostのPathとngrok上のアドレスをマッピングしてくれます。

ngrokのアプリケーションディレクトリと同階層にて下記のコマンドを実行

./ngrok http 8080

https://f094-39-110-209-109.ngrok.io(都度変わるアドレス) にリクエストするとlocalhost:8080 の結果がレスポンスされます。

Twitter Developerに設定する

Twitterのredirect uri も ngrokで設定したものを指定することをお忘れなく!

'twitter' => [
'client_id' => env('TWITTER_CLIENT_ID'),
'client_secret' => env('TWITTER_CLIENT_SECRET'),
'redirect' => ' https://f094-39-110-209-109.ngrok.io /twitter/login/callback',
],

WebサーバーのPATHを通すとは.

PATHが通っていないからErrorになった。という話を聞いたことありますでしょうか。これは、どういう意味でしょうか。

理解し易くするために、サーバーは様々な処理を実行してくれるコマンド群とイメージして下さい。

1. コマンドの在りか

サーバーには様々なディレクトリが存在しています。
コマンドは役割に応じて、複数のディレクトリ配下に待機しています。

例えば、下記のようなディレクトリです。

  • usr/bin
  • usr/sbin
  • local/bin

コマンドがOSでリクエストされるのを待機しております。

2. PATHとは何か。

サーバー上で、下記コマンドを実行して下さい。

env

下記のような環境変数が出力されると思います。 ※一部抜粋

 EB_ENV_NAME=ZZZZZZZZZZZZZZZZ
 MAIL=/var/spool/mail/ec2-user
 PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin
 PWD=/home/ec2-user
 LANG=ja_JP.UTF-8
 HISTCONTROL=ignoredups
 SHLVL=1
 HOME=/home/ec2-user
 LOGNAME=ec2-user
 SSH_CONNECTION=ZZZZZZZZZZZZZZZZ

その中に、 PATH=XXXX の部分が存在するかと思います。
これが、PATHを通す。の、PATHの正体です。

3. 結局、PATHとは何か。

結局のところ、PATHとは何でしょうか。 

OSにコマンドリクエストされた際に、PATHで指定された配下のコマンドを探すよ。

ということです。
つまり、このPATHに指定されていないディレクトリ配下にはコマンドを確認しにいきません。

4. PATHを通す必要がある機会

では、どんな場合にPATHを通す必要がるのでしょうか。

例えば、サーバーにnode.jsをインストールして起動するときなどに必要です。(node.jsのインストール方法によっても異なります。PATHが元々通った状態でインストールされている場合もあります。)

再度、envのPATHを確認してみます。

PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin

下記のディレクトリにはPATHが通っています。

  • /usr/local/bin
  • /usr/bin
  • /usr/local/sbin
  • /usr/sbin
  • /home/ec2-user/.local/bin
  • /home/ec2-user/bin

つまり、コマンドをリクエストされた際にPATHディレクトリ配下に確認して、コマンドが存在していれば、そのコマンドを実行してくれます。

私の環境では、この状態ではnode.jsのPATHが通っておりません。nodeはインストールされているが、コマンドがこのディレクトリに存在していないのです。

nvm use v14.19.0 

した後に、再度 envのPATHを確認します。

PATH=/home/ec2-user/.nvm/versions/node/v14.19.0/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin 

/home/ec2-user/.nvm/versions/node/v14.19.0/bin

が追加されております。このディレクトリ配下にnodeのコマンドが存在しております。そして、このPATH追加によってコマンドを受け入れられる状態になりました。すなわち、PATHが通った状態になりました。

如何でしたでしょうか。PATHを通すとは何かについてイメージを深めて頂けましたでしょうか。

npmビルド時のError:These dependencies were not found:

npmビルド時のError:These dependencies were not found:が出てビルドが中断されました。Errorの原因と解決策を説明していきます。

1. These dependencies were not found: のError原因

直訳すると下記です。

これらの依存関係が存在しません。

おそらくThese dependencies were not found: の下部に対象のライブラリが記述されているかと思います。

Error例
These dependencies were not found: 

* element-ui in ./resources/assets/js/app/index.js
* element-ui/lib/locale/lang/ja in ./resources/assets/js/app/index.js 

要するに、必要なライブラリが存在していない。ということです。

2. ライブラリを確認

実際にライブラリが存在していないかと確認してみましょう。

たとえば、上記のError例でいうと element-ui が存在していないということです。

2-1. package.json

package.jsonに element-ui の記述があるかを確認してみて下さい。おそらく存在しているはずです。(組織開発で他の方がインストールしているはず。)これが、存在していないのであれば、話が変わってきてしまいます…

2-2. node_modules

では、ライブラリが存在しているか、node_modules配下で確認してみましょう。アルファベット順に並んでいるので、element-uiディレクトリが存在しているのかを確認してみて下さい。おそらく無いはずです。

3. 解決策

上記で確認したことを簡単に説明しますと。

  • 組織開発において、他者がライブラリをインストールして開発している。
  • が、node_modules配下にインストールされるJSライブラリは、基本的にはgitignoreで共有されない
  • なので、他者が利用しているライブラリが自分の開発環境には存在しない。

ということになります。

解決方法としては、シンプルです。

pacage.jsonが存在するディレクトリ階層にて、

npm install

を実施して下さい。

pacage.jsonに記述されているライブラリがインストールされます。

再度、ビルドを実行すると該当のErrorは無くなっているかと思います。

Laravelテストで、DataProvider/データプロバイダーの使い方

LaravelのテストでDataProviderを使っていますでしょうか。今回は、DataProviderとは。効果について述べていきます。

0-1. DataProviderとは

Laravel Unitテストにおけるテスト用のデータを生成する仕組みです。Unitテストには、様々なデータ生成の仕組みが存在します。そのうちの1つです。

0-2. DataProviderのメリット

では、様々なデータ生成の仕組みが存在するなかで、DataProviderのメリットはなんでしょうか。それは同じテストにおいて、データのみが異なる場合に非常に簡単に実行してくれます。

例えば、動物かどうかを確認するテスト を実行する際に。
確認するデータ(猿・像・ひまわり・ライオン ) に対して毎回テストを書いていたら面倒ですよね?? これをDataProviderを使えば簡単に全データをテストしてくれます。

1. DataProviderの書き方

1-1. DataProviderのメソッドを書く

> tests/AnimalTest.php

public function test_check_animal(){
//実行されるテスト
}


//これがDataProviderです。
public function animalTestData(){
        return [
            '猿'       => ['肺呼吸', 'move', '光合成ナシ'],
            '像'       => ['肺呼吸', 'move', '光合成ナシ'],
            'ひまわり'  => ['気孔と樹皮', 'stay', '光合成アリ'],
            'ライオン'  => ['肺呼吸', 'move', '光合成ナシ'],
        ];
}

注意点

  1. アクセス修飾子は public
  2. returnの中は連想配列で

1-2. DataProviderをテストメソッドで呼び出す

public function test_check_animal() でDataProviderを使ってみます。

> tests/AnimalTest.php

/**
 * @dataProvider animalTestData
 */
public function test_check_animal(string $breathing, string $move, bool $photosynthesis){
//実行されるテスト

}


//これがDataProviderです。
public function animalTestData(){
        return [
            '猿'       => ['肺呼吸', 'move', '光合成ナシ'],
            '像'       => ['肺呼吸', 'move', '光合成ナシ'],
            'ひまわり'  => ['気孔と樹皮', 'stay', '光合成アリ'],
            'ライオン'  => ['肺呼吸', 'move', '光合成ナシ'],
        ];
}

注意点

  1. DataProviderを利用するテストメソッドの上で、利用するDataProviderを宣言します。
    • @dataProvider animalTestData で宣言している部分です。
  2. テストメソッドでDataProviderのデータを引数で受け取ります。
    • string $breathing, string $move, bool $photosynthesis で引き受けている部分です。

以上です。

猿・像・ひまわり・ライオン の4種類のテストが1つのテストメソッドで実行出来ます。

UnitTest/Laravel5.xから6.xへ変更 | Method ‘XXXX’ is not compatible with method ‘Tests\TestCase::setUp()’.intelephense(1038)

Laravel5.xから6.x へバージョン変更した際に発生したUnitテストのError対処法です。

1. Errorメッセージ

Method 'XXXX' is not compatible with method 'Tests\TestCase::setUp()'.intelephense(1038)

2. Error箇所

    public function setUp(){ // ここでError
        parent::setUp();
    }

3. Errorの意味

'Tests\TestCase::setUp()'と互換性がありません。

どういうことでしょうか?

setUp関数は、use Tests\TestCase; クラスから参照されています。(正確には、更に継承先ののvendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php

ここで記述されている setUp関数を確認すると。

    protected function setUp(): void
    {
         //省略
    }

返り値 void が必須になっています。

4. 修正方法

    public function setUp(): void{ // 返り値を継承先に合わせる
        parent::setUp();
    }

setUp()関数の返り値の型を継承先に合わせてあげます。

これで解決します。

Laravel:privateメソッドに対してUnitテストを実施する方法

privateメソッドに対してUnitテストを実施する方法を紹介します。

0. 前提知識

アクセス修飾子をご存知でしょうか。 class内のメソッド・プロパティに対して外部からのアクセス要件を設定する情報です。public, protected, private とあります。 privateは同一Classからしかアクセス出来ません。

つまり、Unitテストは他のClassから実行するものなので、通常のUnitテストではprivateメソッドに対してテストは実行出来ません。

では、どうやってUnitテストを実施していくのでしょうか。

Laravelには、privateメソッドに対してUnitテストを実行できる環境が用意されているので、そちらを使います。

1. ReflectionClassを利用する

実装方法は非常にシンプルです。

ExampleService内にあるprivateMehtod をUnitテストのPrivateMethodTest で実行します。

ExampleService はざっくりと下記

<?php
class ExampleService 
{
    //省略
    private function privateMehtod() // privateメソッドである
    {
        // メソッド内処理
        return $result;
    }
    //省略
}

UnitテストPrivateMethodTest は下記です。 ReflectionClass の使い方を参照下さい。 下記にて、test_example() にてprivateMehtod を実行してreturnを返しています。

<?php

use ReflectionClass;
use ExampleService;

class PrivateMethodTest extends TestCase
{
    private $reflection;
    private $service;

    public function setUp()
    {
        parent::setUp();
        $this->service = new ExampleService();
        $this->reflection = new ReflectionClass($this->service);
    }

    public function test_example()
    {
        $example_class = new ExampleService();

        $method = $this->reflection->getMethod( 'privateMehtod' );
        $method->setAccessible( true );
        $result = $method->invoke( $this->service );
        // assertでTest確認
        // 省略
    }
}

2. privateメソッドに引数がある場合

privateMehtod に引数 $params がある場合

<?php
class ExampleService 
{
    //省略
    private function privateMehtod( $params ) // privateメソッドである
    {
        // メソッド内処理
        return $result;
    }
    //省略
}

変更箇所で記述しています。

  • invoke( ) -> invokeArgs( )
  • invokeArgs( ) の第2引数に$params を代入
    • 第2引数 は array型で渡す必要があります。
<?php

use ReflectionClass;
use ExampleService;

class PrivateMethodTest extends TestCase
{
     // 省略

    public function test_example()
    {
        // 省略
        $result = $method->invokeArgs( $this->service, [$params] );
        // 省略
    }
}

以上です。

ReflectionMethodを使う方法もありますが、今回はReflectionClass を使う方法を紹介しました。

Laravel5.2でのUnitテスト実行コマンド

物凄くニッチなテーマですが。

Readoubleにもコマンドが書かれていなかったので、備忘録です。

1. アプリフォルダへ移動

2. testsディレクトリ全てのテストを実行

./vendor/bin/phpunit

3. 特定ファイルのテストを実行

./vendor/bin/phpunit tests/テストのファイル名

SQSのメッセージをトリガーにLambdaを起動

以前、Laravelを利用してSQSメッセージを送信する方法を解説しました。こちらの続きです。

SQSメッセージを送信するだけで機能完了することはほぼ無いことだと思います。メッセージを送信した先で、何らかの処理を実行するために用います。
そこでよく使われるのが、Lambdaです。

SQSメッセージをトリガーにして、Lambdaを起動させるまでを簡潔に解説していきます。

0. GOAL

今回のGOALは、SQSのメッセージ送信をトリガーにして、Lambdaを起動させる。そして、起動したことをCloudWatchで確認。

1. Lambdaを作成

1-1. Lambda関数を新規作成

特別な設定は不要です。 今回、Python3.7 で作成していきます。

1-2. Roleを設定

Roleを設定していきます。 SQSをポーリングして、メッセージを受信できるRoleを設定します。

AWSLambdaSQSQueueExecutionRoleを追加します。

1-3. 関数のコードを設定

import json
def lambda_handler(event, context):
    for record in event['Records']:
       payload=record["body"]
       print(str(payload))

CloudWatchへ、SQSのメッセージを送信するだけなので、record["body"]  をprintする。だけの単純な処理です。

2. SQSメッセージ送信をトリガーに設定する

トリガーをLmabdaに設定します。

  • SQSを選択
  • キューを指定

キューを設定することで、キューにメッセージが受信することをトリガーにLambdaが起動されます。

CloudWatchにSQSメッセージがprintされています。確認してみて下さい。

Q. LambdaはSQSメッセージをどのように判定しているのか.

今回、SQSはメッセージを送信していません。その上で、LambdaではトリガーにSQSのキューを指定しただけです。

結論から言うと、LambdaはSQSのメッセージを定期的に確認しにいってます。これをポーリングと言います。

下記ブログで詳しく書いてありましたので、参照してみて下さい。

実は月額30円の定額課金?SQS⇒lambdaの罠

LaravelでAWS/SQSクライアントを作成し、メッセージを送信

AWSのキューイングサービスであるSQSを利用する方法を解説します。

0. AWSアカウントを作成し、SQSでキューを作成

AWSアカウントの作成方法は省略します。

SQSのキュー作成で、1点だけ注意点です。
キュータイプ標準 で作成して下さい。

1. LaravelにAWS-SDKをインストール

AWS-SDKとは、AWSとのAPI通信を簡素かしたパッケージです。LaravelでAWSを利用する際には、aws-sdk-php-laravel を利用する機会が多いかと思います。

すごい簡単にいうと、AWSとの面倒な認証やあれこれをやってくれる処理郡です。

1-1. composer.json へ aws-sdk-php-laravel を追記

composer.json

{
    "require": {
        //省略
        "aws/aws-sdk-php-laravel": "~3.0"
        //省略
    }
}

1-2. aws-sdk-php-laravel をインストール

composer update を実行する。

composer update

実行が完了すると
/vendor/aws 配下にAWS-SDKがインストールされています。

2. Laravel で SQS クライアントを作成し、メッセージを送信する。

Controllerで、SQSキューにメッセージを送信していきます。まずは、SQSのクライアントを作成します。

2-1. SqsClientを作成する

WebApiControllerのsendSqsメソッドの中で、処理を書いてきます。

<?php

namespace App\Http\Controllers;
use Aws\Sqs\SqsClient;

class WebApiController extends Controller
{
    public function sendSqs()
    {
        $config = [
            'credentials' => [
                'key' => env('AWS_SECRET_ACCESS_KEY'),
                'secret' => env('AWS_ACCESS_KEY_ID'),
            ],
            'region' => 'ap-northeast-1', // ご利用のリージョン
            'version' => 'latest',
        ];
        //SQS Clientを作成
        $sqs = SqsClient::factory($config);
    }
}

SqsClientaws-sdk-php-laravel をインストールした際に一緒に含まれています。

$sqs でSQSのClientを作成出来ました。次に $sqs を利用してメッセージを送信していきます。

2-2. SQSにメッセージを送信

上記で作成したクライアントを利用してメッセージを送信します。

<?php

namespace App\Http\Controllers;
use Aws\Sqs\SqsClient;

class WebApiController extends Controller
{
    public function sendSqs()
    {
        $config = [
            'credentials' => [
                'key' => env('AWS_SECRET_ACCESS_KEY'),
                'secret' => env('AWS_ACCESS_KEY_ID'),
            ],
            'region' => 'ap-northeast-1', // ご利用のリージョン
            'version' => 'latest',
        ];
        //SQS Clientを作成
        $sqs = SqsClient::factory($config);

        // SQSのメッセージ
        $value = "piyo";

        // 送りたいSQSのURLを指定
        $sqs_url = env('AWS_SQS_URL');

        $params = [
            'DelaySeconds' => 0,
            'MessageBody' => $value,
            'QueueUrl' => $sqs_url,
        ];

        $result = $sqs->sendMessage($params);
    }
}

上記で、SQSのキューにメッセージを送信出来ます。

Q. SQSのURLはどこにある?

$sqs_url = env('AWS_SQS_URL');

こちらに SQSのURLを設定する必要があります。

それは、キューの画面へいくと確認出来ます。

以上です。