hen*_*rik 4 phpunit laravel eloquent laravel-4
我正在尝试编写一个测试用例,以测试Laravel 4.2中两个Eloquent模型之间的关系的关联和分离
这是我的测试用例:
class BookingStatusSchemaTest extends TestCase
{
private $statusText = "Confirmed";
private $bookingStub;
private $statusStub;
public function testMigrateService()
{
$this->createTestData();
$booking = $this->bookingStub;
$status = $this->statusStub;
/**
* Check that the booking has no status. OK
*/
$this->assertNull($booking->status);
/**
* Check that status has no booking. OK
*/
$this->assertEquals(count($status->bookings), 0);
/**
* Add a status to the booking. OK
*/
$booking->status()->associate($this->statusStub);
/**
* Check that status has a booking. NOT OK - This gives error
*/
$this->assertEquals(count($status->bookings), 1);
/**
* Check that the booking has a status. OK
*/
$this->assertNotNull($booking->status);
/**
* Do NOT delete the status, just set the reference
* to it to null.
*/
$booking->status = null;
/**
* And check again. OK
*/
$this->assertNull($booking->status);
}
private function createTestData()
{
$bookingStatus = BookingStatus::create([
'status' => $this->statusText
]);
$booking = Booking::create([ ]);
$this->bookingStub = $booking;
$this->statusStub = $bookingStatus;
}
}
Run Code Online (Sandbox Code Playgroud)
当我执行它时,我得到:
There was 1 failure:
1) BookingStatusSchemaTest::testMigrateService
Failed asserting that 1 matches expected 0.
Run Code Online (Sandbox Code Playgroud)
预订模式:
class Booking extends Eloquent {
/**
* A booking have a status
*/
public function status()
{
return $this->belongsTo('BookingStatus');
}
}
Run Code Online (Sandbox Code Playgroud)
BookingStatus模型:
class BookingStatus extends Eloquent
{
protected $table = 'booking_statuses';
protected $guarded = [ 'id' ];
protected $fillable = ['status'];
/**
* A booking status belongs to a booking
*/
public function bookings()
{
return $this->hasMany('Booking');
}
}
Run Code Online (Sandbox Code Playgroud)
这是bookingstatus的迁移模式:
Schema::create('booking_statuses', function(Blueprint $table)
{
$table->increments('id');
$table->string('status');
$table->timestamps();
});
Run Code Online (Sandbox Code Playgroud)
和这里预订:
Schema::create('bookings', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('booking_status_id')->nullable();
$table->timestamps();
});
Run Code Online (Sandbox Code Playgroud)
为了验证我的测试用例中的关系,我必须添加/更改什么?
已经有一段时间了,我完全忘记了这个问题。由于OP仍然对此感兴趣,因此我将尝试以某种方式回答该问题。
因此,我认为实际的任务是:如何测试两个Eloquent模型之间的正确关系?
我认为是Adam Wathan最初建议放弃诸如“单元测试”和“功能测试”以及“我没有这种想法的测试”之类的术语,而是将测试分为两个关注点/概念:功能和概念。单位,其中“功能”仅描述应用程序的功能,例如“已登录的用户可以预订机票”,而单位则描述应用程序的较低级别的单位及其提供的功能,例如“预订具有状态”。
我非常喜欢这种方法,因此,我想重构您的测试:
class BookingStatusSchemaTest extends TestCase
{
/** @test */
public function a_booking_has_a_status()
{
// Create the world: there is a booking with an associated status
$bookingStatus = BookingStatus::create(['status' => 'confirmed']);
$booking = Booking::create(['booking_status_id' => $bookingStatus->id]);
// Act: get the status of a booking
$actualStatus = $booking->status;
// Assert: Is the status I got the one I expected to get?
$this->assertEquals($actualStatus->id, $bookingStatus->id);
}
/** @test */
public function the_status_of_a_booking_can_be_revoked()
{
// Create the world: there is a booking with an associated status
$bookingStatus = BookingStatus::create(['status' => 'confirmed']);
$booking = Booking::create(['booking_status_id' => $bookingStatus->id]);
// Act: Revoke the status of a booking, e.g. set it to null
$booking->revokeStatus();
// Assert: The Status should be null now
$this->assertNull($booking->status);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码未经测试!
请注意,函数名称的读取方式类似于预订及其功能的描述。您实际上并不在乎实现,也不必知道Booking在哪里或如何获取其BookingStatus-您只想确保如果存在带有BookingStatus的Booking,则可以获取该BookingStatus。或撤销它。或者也许改变它。还是做什么。测试将显示您如何与该部门互动。因此,编写测试,然后尝试使其通过。
测试的主要缺陷可能是您对某种魔术“有点怕”。而是将您的模型视为普通的旧PHP对象-因为这就是它们!而且您不会在POPO上进行如下测试:
/**
* Do NOT delete the status, just set the reference
* to it to null.
*/
$booking->status = null;
/**
* And check again. OK
*/
$this->assertNull($booking->status);
Run Code Online (Sandbox Code Playgroud)
这是一个非常广泛的话题,关于它的每条陈述都不可避免。有一些准则可以帮助您相处,例如“仅测试您自己的代码”,但是要把所有事情都放在一起真的很难。幸运的是,前面提到的Adam Wathan拥有一个非常出色的视频课程,名为“ Test Driven Laravel ”,他在其中测试驱动了整个真实世界的Laravel应用程序。这可能会花费一些钱,但值得每一分钱,它可以帮助您比StackOverflow上的一些随机花花公子更多地了解测试方法:)
要测试您是否设置了正确的 Eloquent 关系,您必须对关系类 ( $model->relation())运行断言。你可以断言
$model->relation()是HasMany, BelongsTo, HasManyThrough... 等的实例,这是正确的关系类型$model->relation()->getRelated()$model->relation()->getForeignKey()Schema::getColumListing($table)(在这里,$table或者是$model->relation()->getRelated()->getTable()如果它是一个HasMany关系或者$model->relation()->getParent()->getTable()如果它是一个BelongsTo关系)例如。假设您有 aParent和一个Child模型,其中 aParent有很多Child通过children()使用parent_id作为外键的方法。Parent映射parents表并Child映射children表。
$parent = new Parent;
# App\Parent
$parent->children()
# Illuminate\Database\Eloquent\Relations\HasMany
$parent->children()->getRelated()
# App\Child
$parent->children()->getForeignKey()
# 'parent_id'
$parent->children()->getRelated()->getTable()
# 'children'
Schema::getColumnListing($parent->children()->getRelated()->getTable())
# ['id', 'parent_id', 'col1', 'col2', ...]
Run Code Online (Sandbox Code Playgroud)
编辑 此外,这不会触及数据库,因为我们从不保存任何内容。但是,数据库需要迁移,否则模型将不会与任何表相关联。
| 归档时间: |
|
| 查看次数: |
5305 次 |
| 最近记录: |