Mockery1.0 引数のバリデーション

引数のバリデーション

エクスペクションの準備時に、with()宣言へ渡された引数は、エクスペクションと一致するメソッドの基準として判定されます。それにより、期待する引数がそれぞれ異なる、多くのエクスペクションを一つのメソッドに指定できます。このような引数のマッチングは、「一番フィットする」を基本に行われます。これにより、曖昧なマッチャーより明確なマッチャーが優先されます。

明確なマッチとは、引数が期待され、実際の引数が(たとえば、=====を使用し)簡単に同一視できることを単に示します。より曖昧なマッチャーは、正規表現やクラスヒント、一般的なマッチャー などです。曖昧なマッチャーの目的は、明確でない場合の引数を定義することで、with()にその場所の どんな 引数とも一致するMockery::any()が一例です。

Mockeryの曖昧マッチャーは、可能性を全てカバーできませんが、マッチャーのHamcrestライブラリーをサポートしています。Hamcrestは同じ名前のJava(やPython、Erlangなど)のライブラリーをPHPへ移植したものです。Hamcrestを使用することで、MockeryはHamcrestが宣伝している自然な英語のDSLという印象深い利点を再開発せずに済んでいます。

以下の例では、Mocheryのマッチャーと、存在する場合はHamcrestの同じ働きのマッチャーを示します。Hamcrestは(名前空間なしの)関数を使用しています。

Note: グローバルなHamcrest関数を使用したくない場合、静的メソドッドは全て\Hamcrest\Matchersクラスを通じて利用できます。たとえば、identicalTo($arg)は、\Hamcrest\Matchers::identicalTo($arg)とおなじです。

最も汎用されるマッチャーは、with()です。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(1):

これはMockeryに対し、引数に1を渡されたfooメソッドの呼び出しを受け取ることを伝えています。このようなケースでは、Mockeryはまず引数の比較に===(厳密な比較)演算子を使用します。引数がプリミティブで、厳密な比較で不一致の場合、Mockeryは==(緩やかな比較)演算子をフォールバックとして使用します。

オブジェクトの引数のマッチングでは、Mockeryは厳密な===比較だけを行いますので、全く同じ$objectのみ一致します。

$object = new stdClass();
$mock = \Mockery::mock('MyClass');
$mock->shouldReceive("foo")
    ->with($object);

// Hamcrestの同じ動作をするマッチャー
$mock->shouldReceive("foo")
    ->with(identicalTo($object));

別のstdClassインスタンスは、一致 しません

Note: Mockery\Matcher\MustBeマッチャーは使用されなくなりました。

オブジェクトに対してゆるい比較が必要であれば、HamcrestのequalToマッチャーを使用します。

$mock->shouldReceive("foo")
    ->with(equalTo(new stdClass));

引数のタイプや値は気にかけず、どんな引数でも構わない場合、any()を使用します。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive("foo")
    ->with(\Mockery::any());

// Hamcrestの同じ動作をするマッチャー
$mock->shouldReceive("foo")
    ->with(anything())

この引数の場所にはどんなものでも全て渡せ、制約はありません。

タイプとリソースのバリデーション

type()マッチャーは文字列を引数に取り、 タイプチェックを検査するis_形式の関数でマッチングします。

PHPリソースであるかをマッチングするには、以下のように行なえます。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive("foo")
    ->with(\Mockery::type('resource'));

// Hamcrestの同じ動作をするマッチャー
$mock->shouldReceive("foo")
    ->with(resourceValue());
$mock->shouldReceive("foo")
    ->with(typeOf('resource'));

メソッドに指定した引数がPHPのリソースの場合、is_resource()を呼び出し、trueが返ってきます。たとえば、\Mockery::type('float')やHamcrestのfloatValue()typeOf('float')チェックでは、is_float()が使用され、\Mockery::type('callable')やHamcrestcallable()では、is_callable()を使用します。

type()マッチャーは、クラスやインターフェイス名も引数に取り、実際の引数をinstanceofで評価するために使用します。Hamcrestでは、anInstanceOf()を使います。

タイプチェッカーの全リストは、php.netを参照するか、Hamcrestの関数リスト、the Hamcrest codeを閲覧してください。

複雑な引数のバリデーション

複雑な引数のバリデーションを行いたい場合は、on()マッチャーがとても役立ちます。これは実際の引数が渡されるクロージャ(無名関数)を引数に取ります。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive("foo")
    ->with(\Mockery::on(closure));

クロージャの評価(例えば返却値)が、論理型のtrueであれば、その引数はエクスペクションと一致すると判断されます。

$mock = \Mockery::mock('MyClass');

$mock->shouldReceive('foo')
    ->with(\Mockery::on(function ($argument) {
        if ($argument % 2 == 0) {
            return true;
        }
        return false;
    }));

$mock->foo(4); // エクスペクションと一致
$mock->foo(3); // NoMatchingExpectationExceptionを投げる

 

Note: on()にあたる、Hamcrestバージョンのマッチャーは存在しません。

渡されたクロージャで、引数のバリデーションを実行するwithArgs()メソッドも使用できます。クロージャは期待されているメソッドに渡された全引数を受け取り、その評価(例えば返却値)が論理型のtrueの場合、引数のリストはエクスペクションと一致したと判断します。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive("foo")
    ->withArgs(closure);

クロージャはオプショナルな引数も処理でき、期待しているメソッド呼び出しでオプショナルな引数が指定されない場合でも、引数のリストがエクスペクションと一致しないと判定されるのを防ぐことができます。

$closure = function ($odd, $even, $sum = null) {
    $result = ($odd % 2 != 0) && ($even % 2 == 0);
    if (!is_null($sum)) {
        return $result && ($odd + $even == $sum);
    }
    return $result;
};

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')->withArgs($closure);

$mock->foo(1, 2); // オプショナル引数は必須ではない、エクスペクションと一致する
$mock->foo(1, 2, 3); // オプショナル引数はバリデーションに成功、エクスペクションと一致する
$mock->foo(1, 2, 4); // オプショナル引数がバリデーションに失敗、エクスペクションと一致しない

 

Note: 以前のバージョンのMockeryで、with()は引数に対するパターンマッチングを試みました。引数は正規表現だと仮定していました。これは何度も素晴らしいアイデアではないと証明されたため、この機能は削除し、代わりにMockery::pattern()を導入しました。

引数が正規表現と一致するかを調べたい場合は、\Mockery::pattern()を使います。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::pattern('/^foo/'));

// Hamcrestの同じ動作をするマッチャー
$mock->shouldReceive('foo')
    with(matchesPattern('/^foo/'));

ducktype()マッチャーは、クラスタイプのマッチングの別型です。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::ducktype('foo', 'bar'));

呼び出すリスト上のメソッドを含んでいるオブジェクトと一致します。

Note: Hamcrestバージョンには、ducktype()に当たるマッチャーは存在しません。

追加の引数マッチャー

not()マッチャーは、引数と等しくない、もしくは異なる引数であればマッチします。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::not(2));

// Hamcrestの同じ動作をするマッチャー
$mock->shouldReceive('foo')
    ->with(not(2));

anyOf()マッチャーは、指定した引数のどれかと一致する場合にマッチします。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::anyOf(1, 2));

// Hamcrestの同じ動作をするマッチャー
$mock->shouldReceive('foo')
    ->with(anyOf(1,2));

notAnyOf()マッチャーは、指定した引数のどれとも一致しない、もしくは同じでない場合にマッチします。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::notAnyOf(1, 2));

 

Note: HamcrestバージョンのnotAnyOf()マッチャーはありません。

subset()は指定した配列のサブセットを含んでいる、引数の配列と一致します。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::subset(array(0 => 'foo')));

これは、キーと値の両方の一致を強要します。例えば、実際の引数で各要素のキーと値を比較します。

Note: この機能はHamcrestバージョンがありません。しかし、HamcrestではhasEntry()hasKeyValuePair()で、一つの要素をチェックできます。

contains()マッチャーはリストした値を含んでいる配列と一致します。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::contains(value1, value2));

キーは無視されます。

hasKey()マッチャーは、指定したキー値を含んでいる配列と一致します。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::hasKey(key));

hasValue()マッチャーは、指定した値を含んでいる配列と一致します。

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('foo')
    ->with(\Mockery::hasValue(value));

ドキュメント章別ページ

概論

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

バージョン

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる