php 如何在Laravel中分配一个关系而不保存到数据库?

4ktjp1zp  于 12个月前  发布在  PHP
关注(0)|答案(4)|浏览(134)

bounty将在4天后过期。回答此问题可获得+50声望奖励。cytsunny希望引起更多关注此问题:虽然连接到sqlite数据库似乎是一种可能的解决方案,但如果能够将数据直接设置为对象,那就太好了。

我有以下两种型号:

<?php
namespace App\Models;

class Product extends Model
{
    //some other property of the Model

    public function productType() {
        return $this->belongsTo( 'App\Models\ProductType', 'product_type_id');
    }
    
    public function theComplicatedFunctionBeingTested() {
        //Some calculation with consideration of ProductType
        return $result;
    }
}

个字符
现在我想在Product模型中为theComplicatedFunctionBeingTested()编写单元测试,如果没有必要,我不想模拟模型,所以我在单元测试中创建了这些模型的真实的对象。

<?php
use Illumniate\Foundation\Testing\TestCase;

use App\Models\Product;
use App\Models\ProductType;

class ProductFunctionTest extends TestCase
{
    private $testProduct, $testProductType;

    private function commonDataSetUp() {
        $this->testProductType = new ProductType;
        $this->testProductType->product_type_id = 1;
        $this->testProductType->name = "publication";

        $this->testProduct = new Product;
        $this->testProduct->name = "testing product";
        //I tried to assign a relation like this, but this is not working
        $this->testProduct->productType = $this->testProductType;
    }

    public function testComplicatedProductFunction() {
        $this->commonDataSetUp();
        $result = $this->testProduct->theComplicatedFunctionBeingTested();
        $this->assertEquals( 'my_expected_result', $result);
    }
}


但是,关系设置不成功,由于没有设置$this->testProduct->productType,Laravel代码库的默认行为是尝试访问数据库,由于单元测试没有设置数据库连接,因此抛出异常,测试失败。
那么,在没有数据库的情况下,建立关系的正确方法应该是什么?

bfnvny8b

bfnvny8b1#

就像在评论中一样,我自己仍然认为你应该使用工厂,但如果你不想使用工厂,那么我认为这可能会帮助你。你可以通过下面的make命令创建模型的示例,而不需要将它们保存到数据库中。

$this->testProductType = ProductType::make([
   // product type model columns
]);

$this->testProduct = Product::make([
    // product model Columns
]);

字符串
然后将ProductType与Product相关联。

$this->testProduct->productType()->associate($this->testProductType);


我希望这可以解决你的问题。

2w2cym1i

2w2cym1i2#

由于关系是一对多,因此可以使用

  • 保存()=>添加单个ProductType,或者
  • saveMany()=>添加多个ProductType

在本例中,请尝试在调用关系后使用保存()

$this->testProductType = new ProductType;
    $this->testProductType->product_type_id = 1;
    $this->testProductType->name = "publication";

    $this->testProduct = new Product;
    $this->testProduct->name = "testing product";
    // You do need to save this first to gain product_id
    $this->testProduct->save(); 
    $this->testProduct->productType()->save($this->testProductType);

字符串
如果要添加2个或更多ProductType,请尝试以下操作

$this->testProduct->productType()->saveMany([
       new ProductType(['name' => 'Abc']),
       new ProductType(['name' => 'Def']),
       new ProductType(['name' => 'Ghi']),
    ]);

9gm1akwq

9gm1akwq3#

代码波纹管工作正常。因此您可以使用setRelation

<?php

namespace Tests\Unit;

use Illuminate\Database\Eloquent\Model;
use PHPUnit\Framework\TestCase;

class ProductType extends Model
{
    public function products()
    {
        return $this->hasMany(Product::class, 'product_id');
    }
}

class Product extends Model
{
    public function productType()
    {
        return $this->belongsTo(ProductType::class, 'product_type_id');
    }

    public function theComplicatedFunctionBeingTested()
    {
        return $this->productType->name . " " . $this->name;
    }
}

class Test extends TestCase
{
    private $testProduct, $testProductType;

    private function commonDataSetUp()
    {
        $this->testProductType = new ProductType;
        $this->testProductType->product_type_id = 1;
        $this->testProductType->name = "publication";
        $this->testProduct = new Product;
        $this->testProduct->name = "testing product";
        $this->testProduct->setRelation('productType', $this->testProductType);
    }

    public function testComplicatedProductFunction()
    {
        $this->commonDataSetUp();
        $result = $this->testProduct->theComplicatedFunctionBeingTested();
        $this->assertEquals("publication testing product", $result);
    }
}

字符串

qybjjes1

qybjjes14#

你应该试试这个代码

$this->testProduct->setRelation("productType", $this->testProductType);

字符串
setRelation在Laravel的API中有文档记录

相关问题