Mockery1.0 Creating Partial Mocks

Creating Partial Mocks

Partial mocks are useful when we only need to mock several methods of an object leaving the remainder free to respond to calls normally (i.e. as implemented). Mockery implements three distinct strategies for creating partials. Each has specific advantages and disadvantages so which strategy we use will depend on our own preferences and the source code in need of mocking.

We have previously talked a bit about creating-test-doubles-partial-test-doubles, but we'd like to expand on the subject a bit here.

  1. Runtime partial test doubles
  2. Generated partial test doubles
  3. Proxied Partial Mock

Runtime partial test doubles

A runtime partial test double, also known as a passive partial mock, is a kind of a default state of being for a mocked object.

$mock = \Mockery::mock('MyClass')->makePartial();

With a generated partial, we assume that all methods will simply defer to the parent class (MyClass) original methods unless a method call matches a known expectation. If we have no matching expectation for a specific method call, that call is deferred to the class being mocked. Since the division between mocked and unmocked calls depends entirely on the expectations we define, there is no need to define which methods to mock in advance.

See the cookbook entry on ../cookbook/big_parent_class for an example usage of runtime partial test doubles.

The makePartial() method is identical to the original shouldDeferMissing() method which first introduced this Partial Mock type. To know more about shouldDeferMissing() method - see the chapter on creating-test-doubles-behavior-modifiers.

Generated Partial Test Doubles

A generated partial test double, also known as a traditional partial mock, defines ahead of time which methods of a class are to be mocked and which are to be left unmocked (i.e. callable as normal). The syntax for creating traditional mocks is:

$mock = \Mockery::mock('MyClass[foo,bar]');

In the above example, the foo() and bar() methods of MyClass will be mocked but no other MyClass methods are touched. We will need to define expectations for the foo() and bar() methods to dictate their mocked behaviour.

Don't forget that we can pass in constructor arguments since unmocked methods may rely on those!

$mock = \Mockery::mock('MyNamespace\MyClass[foo]', array($arg1, $arg2));

See the creating-test-doubles-constructor-arguments section to read up on them.

Even though we support generated partial test doubles, we do not recommend using them.

Proxied Partial Mock

A proxied partial mock is a partial of last resort. We may encounter a class which is simply not capable of being mocked because it has been marked as final. Similarly, we may find a class with methods marked as final. In such a scenario, we cannot simply extend the class and override methods to mock - we need to get creative.

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

Yes, the new mock is a Proxy. It intercepts calls and reroutes them to the proxied object (which we construct and pass in) for methods which are not subject to any expectations. Indirectly, this allows we to mock methods marked final since the Proxy is not subject to those limitations. The tradeoff should be obvious - a proxied partial will fail any typehint checks for the class being mocked since it cannot extend that class.

Special Internal Cases

All mock objects, with the exception of Proxied Partials, allows us to make any expectation call to the underlying real class method using the passthru() expectation call. This will return values from the real call and bypass any mocked return queue (which can simply be omitted obviously).

There is a fourth kind of partial mock reserved for internal use. This is automatically generated when we attempt to mock a class containing methods marked final. Since we cannot override such methods, they are simply left unmocked. Typically, we don't need to worry about this but if we really really must mock a final method, the only possible means is through a Proxied Partial Mock. SplFileInfo, for example, is a common class subject to this form of automatic internal partial since it contains public final methods used internally.

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュを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)へ移動

その他

?

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