31

PHPUnit テストでモック オブジェクト (Mockery) を使用したいと考えています。モック オブジェクトには、いくつかのパブリック メソッドといくつかのパブリック プロパティ セットの両方が必要です。クラスは Laravel Eloquent モデルです。私はこれを試しました:

$mock = Mockery::mock('User');
$mock->shouldReceive('hasRole')->once()->andReturn(true); //works fine
$mock->roles = 2; //how to do this? currently returns an error
$this->assertTrue(someTest($mock));

...しかし、パブリック プロパティを設定すると、次のエラーが返されます。

BadMethodCallException: メソッド Mockery_0_User::setAttribute() がこのモック オブジェクトに存在しません

このエラーは、単純なクラスをモックするときには返されませんが、Eloquent モデルをモックしようとすると返されます。私は何を間違っていますか?

4

8 に答える 8

24

この値でこのプロパティを取得したい場合は、それを使用してください:

$mock->shouldReceive('getAttribute')
    ->with('role')
    ->andReturn(2);

あなたが呼び出す$user->roleと、 - 2 ( $user- そのUserモッククラス)が得られます

于 2014-10-24T20:02:53.060 に答える
8

この回答は少し遅れていますが、誰かの役に立てば幸いです。現在、'alias' キーワードを使用して、モックされた Eloquent オブジェクトに静的プロパティを設定できます。

$mocked_model = Mockery::mock('alias:Namespace\For\Model');
$mocked_model->foo = 'bar';
$this->assertEquals('bar', $mocked_model->foo);

これは、一部の Stripe オブジェクトなどの外部ベンダー クラスをモックする場合にも役立ちます。

「エイリアス」および「オーバーロード」キーワードについて読む: http://docs.mockery.io/en/latest/reference/startup_methods.html

于 2015-08-21T22:23:25.380 に答える
3

あなたの質問に答えるために、次のようなことを試すこともできます。

$mock = Mockery::mock('User');
$mock->shouldReceive('hasRole')->once()->andReturn(true); //works fine
$mock->shouldReceive('setAttribute')->passthru();
$mock->roles = 2; 

$mock->shouldReceive('getAttribute')->passthru();
$this->assertEquals(2, $mock->roles);

または、seblaze で提案されているように、部分的なモックを使用します。

$mock = Mockery::mock('User[hasRole]');
$mock->shouldReceive('hasRole')->once()->andReturn(true);
$mock->roles = 2; 
$this->assertEquals(2, $mock->roles);

ただし、コード スニペットから、単体テストを作成している場合は、実際には各テストごとに 1 つのアサーションのみを作成する必要があります。

function test_someFunctionWhichCallsHasRole_CallsHasRole() {
    $mock = Mockery::mock('User');
    $mock->shouldReceive('hasRole')->once();

    $mock->someFunctionWhichCallsHasRole();
}

function test_someFunctionWhichCallsHasRole_hasRoleReturnsTrue_ReturnsTrue() {
    $mock = Mockery::mock('User');
    $mock->shouldReceive('hasRole')->once()->andReturn(true);

    $result = $mock->someFunctionWhichCallsHasRole();

    $this->assertTrue($result);
}        
于 2014-04-18T22:49:37.700 に答える
0

部分的なモックをしようとしましたか? ( NOT TESTED ) のようなものを試すことができます:

$mock = Mockery::mock('User[hasRole]');
$mock->shouldReceive('hasRole')->once()->andReturn(true);
$mock->roles = 2; 
$this->assertTrue(someTest($mock));
于 2014-04-08T07:39:11.997 に答える
0

これを試しましたか?それはあなたの問題をカバーするはずです。

https://github.com/padraic/mockery/blob/master/docs/11-MOCKING-PUBLIC-PROPERTIES.md

これらを実装すると思います

protected $roles = array();

public function setRoles($roles)
{
    $this->roles = $roles;
}

public function addRole($role)
{
    $this->roles[] = $role;
}

次に、次を使用してテストできます。

$mock = Mockery::mock('User');
$mock->shouldReceive('hasRole')->once()->andReturn(true);
$mock->addRole(2);
$this->assertTrue(someTest($mock));

この後陣は、SOLID OOP を実行する場合、または配列を使用する場合、少なくとも getRoles() を実行するときに、Role オブジェクトの配列になるフォーマットを約束する機会を提供します。

于 2014-04-07T10:03:46.153 に答える
0

Laravel 5.3 の部分モック

$mock = Mockery::mock(App\User::class)->makePartial();
$mock->shouldReceive('hasRole')->once()->andReturn(true);
$mock->roles = 2; 
$this->assertEquals(2, $mock->roles);
于 2018-09-06T17:19:57.720 に答える
-3

この場合、stdclass を使用できます。

$obj = new stdClass();
$obj->roles = 2;
$mock = Mockery::mock('User');
// return stdclass here.
$mock->shouldReceive('hasRole')->once()->andReturn($obj);
$mock->roles = 2;
$this->assertEquals(2, $mock->roles);
于 2016-09-12T15:19:48.803 に答える