如何通过相关模型实现的接口测试可验证多态关系的模型?

问题描述

这一切都在Laravel 7上。我正在使用PHPUnit / Laravel提供的内置测试套件。

我有一个rating模型(请参见下面的代码),该模型具有称为content(作为名称)的多态关系。创建此模型后,只有使用content来实现RateableInterface时,它才会接受instanceof

现在,要对此进行测试,我目前正在使用另一个名为Entity的模型。它确实实现了RateableInterface,因此测试代码可以正常工作。但是,我真的很想将Entity与我的ratingTest分开,因为我知道单元测试应该是隔离的,并且不依赖于外部代码。如果将Entity更改为 not 实施RateableInterface,这会给我的测试带来问题,但是实际上Entity不会有太多问题与rating有关。

创建一个Entity的存根,但是在检查content是否实现RateableInterface之前,我先检查content是否存在于数据库中。最重要的是,我的目标是使该测试与Entity分离,所以这并不是我真正想做的事情。

我也试图创建一个RateableInterface的存根,但是由于上述原因,它也不起作用:它在数据库中将不存在。即使可以保存存根,我也没有为此使用的表,我也不认为为此创建迁移是前进的正确方法(如果我错了,请纠正我)。除此之外,我尝试在实现RateableInterface的测试文件中创建一个新类,但是同样,我将不得不进行新的迁移,我认为这不是正确的答案。

我已经花了几个小时,而且我真的不确定如何在不使用RateableInterface之类的Entity特定实现的情况下进行测试。任何帮助将不胜感激。

此外,正如您将在下面看到的那样,该界面具有canRate(),这也是我想离开Entity的另一个原因。存根将解决此问题,它能够定义该方法将返回的内容,但是我已经解释了为什么该方法不起作用。

代码

rating

<?PHP

// ...

class rating
{
    public function content()
    {
        return $this->content;
    }

    // ...
    
    public function canCreate(): bool
    {
        // Check if content exists in the db.
        if (!$this->content) {
            return false;
        }

        // Check if content implements RateableInterface
        if (!$this->content instanceof RateableInterface) {
            return false;
        }

        if (!$this->content->canRate()) {
            return false;
        }

        return true;
    }

    // ...
}

RateableInterface

<?PHP

// ...

interface RateableInterface
{
    public function canRate(): bool;
}

Entity

<?PHP

// ...

class Entity implements RateableInterface
{
    public function ratings(): MorphMany
    {
        return $this->morphMany(rating::class,'content');
    }

    // ...
    
    public function canRate(): bool
    {
        // Do some work...
        // Check for X and Y...
        return true;
    }

    // ...
}

ratingTest

<?PHP

// ...

class ratingTest extends TestCase
{
    public function testThatCanCreateReturnsTrueOnSuccess()
    {
        // I want to replace this so this test does not rely on Entity.
        $entity = factory(Entity::class)->create();
        $rating = new rating(
            [
                'content_id' => $entity->id,'content_type' => 'Entity',// This is resolved
            ]
        }

        self::assertTrue($rating->canCreate());
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)