MorphToMany关联在我的测试中无法正常工作。

huangapple go评论67阅读模式
英文:

MorphToMany relation doesn't work properly in my test

问题

在我的Laravel项目中,我使用morphToMany关系将成本与订单和订单中的产品连接起来。

我有这个迁移:

Schema::create('costables', function (Blueprint $table) {
    $table->unsignedBigInteger('cost_id');
    $table->morphs('costable');

    $table->foreign('cost_id')
        ->references('id')->on('costs')
        ->onUpdate('cascade')
        ->onDelete('cascade');
});

这是订单模型,其中包含costs()方法:

namespace Domain\Webshop\Models;

use Domain\Customer\Models\Address;
use Domain\Customer\Models\Member;
use Domain\Product\Models\Cost;
use Domain\Webshop\Database\Factories\OrderFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

class Order extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'member_id',
        'shipping_address_id',
        'billing_address_id',
        'status',
    ];

    public static $rules = [
        'member_id' => 'required|integer',
        'shipping_address_id' => 'sometimes|integer',
        'billing_address_id' => 'nullable|integer',
        'status' => 'required|integer',
    ];

    protected $casts = [
        'member_id' => 'integer',
        'shipping_address_id' => 'integer',
        'billing_address_id' => 'integer',
    ];


    protected $hidden = ['created_at', 'updated_at', 'deleted_at'];

    /**
     * Create a new factory instance for the model.
     *
     * @return \Illuminate\Database\Eloquent\Factories\Factory
     */
    protected static function newFactory(): OrderFactory
    {
        return OrderFactory::new();
    }

    public function member(): BelongsTo
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    public function shippingAddress(): BelongsTo
    {
        return $this->belongsTo(Address::class, 'shipping_address_id');
    }

    public function costs(): MorphToMany
    {
        return $this->morphToMany(Cost::class, 'costable');
    }
}

这是我的phpunit测试,用于测试订单和订单产品模型上的成本。$this->model是实际模型,我将其用作特性:

/** @test */
public function shouldHasCosts()
{
    $item = $this->model::factory()
        ->hasCosts(1)
        ->create();

    $this->assertInstanceOf(
        Cost::class,
        $item->first()->costs()->first(),
        "It should be defined a relation called costs on $this->model"
    );
}

我的问题是,在订单模型的情况下,测试成功,但在订单产品模型中失败了。我忘记了什么,或者我的代码有什么问题?

英文:

In my laravel project I use morphToMany relation to connect costs to the orders and products of the orders.

I have this migration:

Schema::create('costables', function (Blueprint $table) {
    $table->unsignedBigInteger('cost_id');
    $table->morphs('costable');

    $table->foreign('cost_id')
        ->references('id')->on('costs')
        ->onUpdate('cascade')
        ->onDelete('cascade');
});

This is the Order model, with costs() method in it:

namespace Domain\Webshop\Models;

use Domain\Customer\Models\Address;
use Domain\Customer\Models\Member;
use Domain\Product\Models\Cost;
use Domain\Webshop\Database\Factories\OrderFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

class Order extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'member_id',
        'shipping_address_id',
        'billing_address_id',
        'status',
    ];

    public static $rules = [
        'member_id' => 'required|integer',
        'shipping_address_id' => 'sometimes|integer',
        'billing_address_id' => 'nullable|integer',
        'status' => 'required|integer',
    ];

    protected $casts = [
        'member_id' => 'integer',
        'shipping_address_id' => 'integer',
        'billing_address_id' => 'integer',
    ];


    protected $hidden = ['created_at', 'updated_at', 'deleted_at'];

    /**
     * Create a new factory instance for the model.
     *
     * @return \Illuminate\Database\Eloquent\Factories\Factory
     */
    protected static function newFactory(): OrderFactory
    {
        return OrderFactory::new();
    }

    public function member(): BelongsTo
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    public function shippingAddress(): BelongsTo
    {
        return $this->belongsTo(Address::class, 'shipping_address_id');
    }

    public function costs(): MorphToMany
    {
        return $this->morphToMany(Cost::class, 'costable');
    }
}

And this is my phpunit test, for testing costs on the Order and OrderProduct models. The $this->model is the actual model, I use this as a trait:

/** @test */
public function shouldHasCosts()
{
    $item = $this->model::factory()
        ->hasCosts(1)
        ->create();

    $this->assertInstanceOf(
        Cost::class,
        $item->first()->costs()->first(),
        "It should be defined a relation called costs on $this->model"
    );
}

My problem is, the test success in the Order model case, but fails at the OrderProduct. What have I forgotten, or whats wrong in my code?

答案1

得分: 1

我自己找到了问题:在测试的设置中,对OrderProduct进行了工厂创建,因此在数据库中有两行数据,而shouldHasCosts()测试检查的是first(),所以是错误的。我删除了不必要的创建,问题得以解决。

英文:

I found the problem myself: in the test's setup there was a factory create for the OrderProduct, so in that case there was two rows in the database, and the shouldHasCosts() test is examine the first(), so it was wrong. I deleted the unnecessary create, and it has solved the problem.

huangapple
  • 本文由 发表于 2023年1月9日 19:35:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056702.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定