【PHP】配列の要素をチェックするプログラムとそのユニットテスト

配列の要素をチェックするプログラムとそのPHPUnitのテストコードです。
どちらかというとテストコードがメインです。

ソースコード

https://github.com/masaki-code/php/blob/master/array/src/Arrays.php

空の判定

private static function isEmpty($param, $key)
{
    if (! isset($param[$key])) {
        return true;
    }

    $value = $param[$key];

    if (is_string($value) && $value === '') {
        return true;
    }

    return false;
}

配列paramと配列のキーkeyを受け取って、配列の値が空かをチェックする関数です。
基本的にはissetで要素があるかをチェックしていますが、文字列の場合は空文字でないかもチェックしています。

空のチェックと例外

private function checkEmpty($key, $message, ErrorCode $errorCode)
{
    if (self::isEmpty($this->array, $key)) {
        throw new InnerException($message, $errorCode);
    }
    return $this->array[$key];
}

空の判定をして、空の場合に例外を投げる関数です。

なお、InnerExceptionとErrorCodeは個人的にクラス化したものです。
詳細は気にする必要はないと思いますが、もし気になる方がいる場合はgithubの方を見てもらえればお思います。

メイン

public function checkArrays(): self
 {
     $value_1 = $this->checkEmpty('key_1', 'key_1 empty', ErrorCode::EMPTY_1());
     $value_2 = $this->checkEmpty('key_2', 'key_2 empty', ErrorCode::EMPTY_2());
     $value_3 = $this->checkEmpty('key_3', 'key_3 empty', ErrorCode::EMPTY_1());
     $value_4 = $this->checkEmpty('key_4', 'key_4 empty', ErrorCode::EMPTY_2());
     $value_5 = $this->checkEmpty('key_5', 'key_5 empty', ErrorCode::EMPTY_1());
     $value_6 = $this->checkEmpty('key_6', 'key_6 empty', ErrorCode::EMPTY_2());
 }

空のチェックを実施するプログラムです。
複数のキーをチェックするようになっており、それぞれでエラー時のメッセージとエラーコードを指定するようになっています。

テストコード

https://github.com/masaki-code/php/blob/master/array/tests/ArraysTest.php

正常系

public function test_checkArrays_success()
{
    $array = $this->correctParams();
    $arrays = new Arrays($array);
    $actual = $arrays->checkArrays();
    $this->assertInstanceOf(Arrays::class, $actual);
}

正常系のテストです。
correctParamsは後述しますがテスト用の補助メソッドで、正しい配列を返します。

補助メソッド:正常配列

private function correctParams(): array
{
    $array = [];
    $array['key_1'] = 'value_1_A';
    $array['key_2'] = 'value_2_A';
    $array['key_3'] = 'value_3_A';
    $array['key_4'] = 'value_4_A';
    $array['key_5'] = 'value_5_A';
    $array['key_6'] = 'value_6_A';
    return $array;
}

正しい配列を定義しています。
正常系のテストで使っている他にも異常系のテストデータ作成のベースになっています。

異常系

/**
 * @test
 * @expectedException InnerException
 * @dataProvider emptyDataProvider
 * @dataProvider emptyStringDataProvider
 */
public function test_checkArrays_Exception($array, $msg, $code)
{
    try {
        $arrays = new Arrays($array);
        $arrays->checkArrays();
    } catch (InnerException $e) {
        $this->assertEquals($msg, $e->getMessage());
        $this->assertEquals($code, $e->errorCode()->get());
        throw $e;
    }

    $this->fail('fail');
}

異常系(例外発生系)のテストです。

dataProviderからテスト用のパラメータarray、msg、codeを受け取るようになっています。
発生した例外のメッセージとコードをチェックしています。

また、dataProviderは複数指定できるので、今回は2つに分けています。

補助メソッド:配列の値の削除

private function empty($key)
{
    $array = $this->correctParams();
    unset($array[$key]);
    return $array;
}

正常な配列から指定されたキーを削除して残りの配列を返す関数です。

補助メソッド:配列の値の設定

private function set($key, $value)
{
    $array = $this->correctParams();
    $array[$key] = $value;
    return $array;
}

正常な配列に指定されたキーと値を設定した配列を返す関数です。

dataProvider:配列要素なしのテスト

    public function emptyDataProvider()
    {
        $arrays = [];
        $arrays['key_1 empty test'] = [$this->empty('key_1')];
        $arrays['key_2 empty test'] = [$this->empty('key_2')];
        $arrays['key_3 empty test'] = [$this->empty('key_3')];
        $arrays['key_4 empty test'] = [$this->empty('key_4')];
        $arrays['key_5 empty test'] = [$this->empty('key_5')];
        $arrays['key_6 empty test'] = [$this->empty('key_6')];

        $msg = [];
        $msg['key_1 empty test'] = ['key_1 empty'];
        $msg['key_2 empty test'] = ['key_2 empty'];
        $msg['key_3 empty test'] = ['key_3 empty'];
        $msg['key_4 empty test'] = ['key_4 empty'];
        $msg['key_5 empty test'] = ['key_5 empty'];
        $msg['key_6 empty test'] = ['key_6 empty'];

        $code = [];
        $code['key_1 empty test'] = ['EMPTY_1'];
        $code['key_2 empty test'] = ['EMPTY_2'];
        $code['key_3 empty test'] = ['EMPTY_1'];
        $code['key_4 empty test'] = ['EMPTY_2'];
        $code['key_5 empty test'] = ['EMPTY_1'];
        $code['key_6 empty test'] = ['EMPTY_2'];

        $p = array_merge_recursive($arrays, $msg, $code);

        return $p;
    }

異常系のテストデータを提供するdataProviderです。
これは配列に要素がない場合のテストデータです。

順番に見ていくと

$arrays['key_1 empty test'] = [$this->empty('key_1')];

は、テスト対象となる配列を定義しています。
先に紹介した関数を使って、特定のキーのみが存在しない配列を設定しています。

続いて

$msg['key_1 empty test'] = ['key_1 empty'];

は、例外発生時のメッセージを定義しています。

また、

$code['key_1 empty test'] = ['EMPTY_1'];

は、例外発生時のエラーコードを定義しています。

最後に

$p = array_merge_recursive($arrays, $msg, $code);

は、今回作成したソースコード、テストコード全体の中で一番のポイントとなっています。

先ほど定義したテスト対象の配列、メッセージ(エラーメッセージ)、エラーコードをマージした配列を作成しています。

通常、

$p['key_1 empty test'] = [$this->empty('key_1'),'key_1 empty','EMPTY_1'];

のように定義すれば良いですし、今回のプログラムでは高々3要素なのでこれで十分です。

ただ、テスト要素が増えてきたり、一つ一つの要素が複雑になったりすると整理が難しくなってくるので、このような方法を取っています。

テストコード実装の際のポイントとしては、「array_merge_recursive」でマージする要素の値を全て配列にしていることです。

配列にしておかないと、arraysの要素の末尾にmsgとcodeが追加されてしまうだけになります。

最初、これがうまく行かず、試行錯誤した結果、この方法でうまくいくことが分かりました。

dataProvider:配列要素が空文字のテスト

    public function emptyStringDataProvider()
    {
        $arrays = [];
        $arrays['key_1 empty string test'] = [$this->set('key_1', '')];
        $arrays['key_2 empty string test'] = [$this->set('key_2', '')];
        $arrays['key_3 empty string test'] = [$this->set('key_3', '')];
        $arrays['key_4 empty string test'] = [$this->set('key_4', '')];
        $arrays['key_5 empty string test'] = [$this->set('key_5', '')];
        $arrays['key_6 empty string test'] = [$this->set('key_6', '')];

        $msg = [];
        $msg['key_1 empty string test'] = ['key_1 empty'];
        $msg['key_2 empty string test'] = ['key_2 empty'];
        $msg['key_3 empty string test'] = ['key_3 empty'];
        $msg['key_4 empty string test'] = ['key_4 empty'];
        $msg['key_5 empty string test'] = ['key_5 empty'];
        $msg['key_6 empty string test'] = ['key_6 empty'];

        $code = [];
        $code['key_1 empty string test'] = ['EMPTY_1'];
        $code['key_2 empty string test'] = ['EMPTY_2'];
        $code['key_3 empty string test'] = ['EMPTY_1'];
        $code['key_4 empty string test'] = ['EMPTY_2'];
        $code['key_5 empty string test'] = ['EMPTY_1'];
        $code['key_6 empty string test'] = ['EMPTY_2'];

        $p = array_merge_recursive($arrays, $msg, $code);

        return $p;
    }

異常系のテストデータを提供するdataProviderです。
これは配列の要素が空文字の場合のテストデータです。

詳しくは先ほど説明しているので、ここでは特記事項は特にありません。

最後に

今回作成したコードの全体は以下にあるので、省略している部分など気になる方はこちらを見てもらえればと思います。

https://github.com/masaki-code/php/tree/master/array

コメント

タイトルとURLをコピーしました