PHPUnit问题断言mock是一个使用Laravel的ReflectionProperty对象


PHPUnit issue asserting mock is a ReflectionProperty object using Laravel

我是PHPUnit的新手,我正在尝试设置我的第一个测试。失败时显示以下错误消息

断言ReflectionProperty Object(…)是类"Illuminate'Database'Eloquent'Model"的实例失败。

本质上,我试图模拟模型的创建,我将其注入构造函数并通过反射测试它是正确的类型。我正在遵循这篇文章/答案中列出的建议:

如何使用phpunit测试这个类?

如果有人能给我一些指导,我将不胜感激。

被测试的类在这里:

<?php
namespace PlaneSaleing'Repo'Listing;
use Illuminate'Database'Eloquent'Model;
class EloquentListing implements ListingInterface {
    protected $advert;
    public function __construct(Model $advert)
    {
        $this->advert = $advert;
    }
    /**
     * Get paginated listings
     *
     * @param int  Current page
     * @param int Number of listings per page
     * @return StdClass object with $items and $totalItems for pagination
     */
    public function byPage($page=1, $limit=10)
    {
        $result = new 'StdClass;
        $result->page = $page;
        $result->limit = $limit;
        $result->totalItems = 0;
        $result->items = array();
        $listings = $this->advert
                         ->orderBy('created_at')
                         ->skip( $limit * ($page-1) )
                         ->take($limit)
                         ->get();
        // Create object to return data useful for pagination
        $result->items = $listings->all();
        $result->totalItems = $this->totalListings();
        return $result;
    }

服务提供者在这里:

<?php
namespace PlaneSaleing'Repo;
use Illuminate'Support'ServiceProvider;
use PlaneSaleing'Repo'Listing'EloquentListing as Listing;
use 'Advert;
class RepoServiceProvider extends ServiceProvider {
    public function register()
    {
      $this->app->bind('PlaneSaleing'Repo'Listing'ListingInterface', function($app) {
        $app->make(Listing(new Advert));
      } );
    }
}

My Test is here:

<?php
use 'Mockery;
use 'ReflectionClass;
use PlaneSaleing'Repo'Listing'EloquentListing;
class EloquentListingTest extends 'TestCase
{
    /**
     * Testing if __constructor is setting up property
     */
    public function testModelSetsUp()
    {
        $mock1 = Mockery::mock(Illuminate'Database'Eloquent'Model::class);
        $listing = new EloquentListing($mock1);
        $reflection = new ReflectionClass($listing);
        // Making your attribute accessible
        $property1 = $reflection->getProperty('advert');
        $property1->setAccessible(true);
        $this->assertInstanceOf(Illuminate'Database'Eloquent'Model::class, $property1);
    }

当你断言时,你应该使用反射属性的实际值,而不是属性本身:

public function testModelSetsUp()
{
    $mock1 = Mockery::mock(Illuminate'Database'Eloquent'Model::class);
    $listing = new EloquentListing($mock1);
    $reflection = new ReflectionClass($listing);
    // Making your attribute accessible
    $property1 = $reflection->getProperty('advert');
    $property1->setAccessible(true);
    $this->assertInstanceOf(
        Illuminate'Database'Eloquent'Model::class, 
        $property1->getValue($listing)
    );
}

但是,您可以大大简化测试:

public function testModelSetsUp()
{
    $mock1 = Mockery::mock(Illuminate'Database'Eloquent'Model::class);
    $listing = new EloquentListing($mock1);
    $this->assertAttributeInstanceOf(
        Illuminate'Database'Eloquent'Model::class, 
        'advert', 
        $listing
    );
}

更好的是,您可以使用有意义的变量名,使用有意义的测试方法名,并且不仅断言$advert属性是Illuminate'Database'Eloquent'Model的实例,而且实际上是传递给构造函数的相同的实例:

public function testConstructorSetsAdvert()
{
    $advert = Mockery::mock(Illuminate'Database'Eloquent'Model::class);
    $listing = new EloquentListing($advert);
    $this->assertAttributeSame(
        $advert,
        'advert',
        $listing
    );
}