Skip to content

Commit ee9a6c2

Browse files
authored
Merge pull request #2 from Astrotomic/issue-1
add model assertion that two models are related
2 parents 0ce82cd + 52bb5d9 commit ee9a6c2

File tree

5 files changed

+144
-23
lines changed

5 files changed

+144
-23
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ This will prevent any method name conflicts with core, your custom or other trai
135135
```php
136136
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertExists($model);
137137
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertSame($model, \App\Models\User::first());
138+
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertRelated($post, 'comments', $comment);
139+
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertRelated(
140+
$post,
141+
'comments',
142+
\App\Models\Comment::class,
143+
\Illuminate\Database\Eloquent\Relations\HasMany::class
144+
);
138145
```
139146

140147
### Blade

src/Laravel/ModelAssertions.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
namespace Astrotomic\PhpunitAssertions\Laravel;
44

55
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Database\Eloquent\Relations\Relation;
67
use Illuminate\Support\Facades\DB;
78
use Illuminate\Testing\Constraints\HasInDatabase;
89
use PHPUnit\Framework\Assert as PHPUnit;
910

1011
trait ModelAssertions
1112
{
13+
/**
14+
* @param string|\Illuminate\Database\Eloquent\Model $table
15+
* @param array $data
16+
* @param string|null $connection
17+
*/
1218
public static function assertExists($table, array $data = [], ?string $connection = null): void
1319
{
1420
if ($table instanceof Model) {
@@ -27,10 +33,43 @@ public static function assertExists($table, array $data = [], ?string $connectio
2733
);
2834
}
2935

36+
/**
37+
* @param \Illuminate\Database\Eloquent\Model $expected
38+
* @param \Illuminate\Database\Eloquent\Model|mixed $actual
39+
*/
3040
public static function assertSame(Model $expected, $actual): void
3141
{
3242
PHPUnit::assertInstanceOf(get_class($expected), $actual);
3343
PHPUnit::assertSame($expected->exists, $actual->exists);
3444
PHPUnit::assertTrue($expected->is($actual));
3545
}
46+
47+
/**
48+
* @param \Illuminate\Database\Eloquent\Model $model
49+
* @param string $relation
50+
* @param string|\Illuminate\Database\Eloquent\Model|mixed $actual
51+
* @param string|null $type
52+
*/
53+
public static function assertRelated(Model $model, string $relation, $actual, ?string $type = null)
54+
{
55+
PHPUnit::assertTrue(method_exists($model, $relation));
56+
PHPUnit::assertInstanceOf(Relation::class, $model->$relation());
57+
58+
if ($type) {
59+
PHPUnit::assertInstanceOf($type, $model->$relation());
60+
}
61+
62+
$related = $model->$relation()->getRelated();
63+
PHPUnit::assertInstanceOf(Model::class, $related);
64+
65+
if (is_string($actual)) {
66+
PHPUnit::assertInstanceOf($actual, $related);
67+
} else {
68+
PHPUnit::assertInstanceOf(get_class($actual), $related);
69+
self::assertSame(
70+
$actual,
71+
$model->$relation()->whereKey($actual->getKey())->first()
72+
);
73+
}
74+
}
3675
}

tests/Laravel/ModelAssertionsTest.php

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,19 @@
33
namespace Astrotomic\PhpunitAssertions\Tests\Laravel;
44

55
use Astrotomic\PhpunitAssertions\Laravel\ModelAssertions;
6-
use Illuminate\Database\Eloquent\Model;
7-
use Illuminate\Database\Schema\Blueprint;
8-
use Illuminate\Support\Facades\Schema;
6+
use Astrotomic\PhpunitAssertions\Tests\Laravel\Models\Comment;
7+
use Astrotomic\PhpunitAssertions\Tests\Laravel\Models\Post;
8+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9+
use Illuminate\Database\Eloquent\Relations\HasMany;
910

1011
final class ModelAssertionsTest extends TestCase
1112
{
1213
protected function setUp(): void
1314
{
1415
parent::setUp();
1516

16-
Schema::create('posts', static function (Blueprint $table): void {
17-
$table->increments('id');
18-
$table->string('title');
19-
$table->timestamps();
20-
});
17+
Post::migrate();
18+
Comment::migrate();
2119
}
2220

2321
/**
@@ -26,15 +24,11 @@ protected function setUp(): void
2624
*/
2725
public function it_can_validate_exists(): void
2826
{
29-
$model = new class extends Model {
30-
protected $table = 'posts';
31-
protected $guarded = [];
32-
};
27+
$post = Post::create([
28+
'title' => self::randomString(),
29+
]);
3330

34-
$model->title = self::randomString();
35-
$model->save();
36-
37-
ModelAssertions::assertExists($model);
31+
ModelAssertions::assertExists($post);
3832
}
3933

4034
/**
@@ -43,14 +37,38 @@ public function it_can_validate_exists(): void
4337
*/
4438
public function it_can_validate_same(): void
4539
{
46-
$model = new class extends Model {
47-
protected $table = 'posts';
48-
protected $guarded = [];
49-
};
40+
$post = Post::create([
41+
'title' => self::randomString(),
42+
]);
43+
44+
ModelAssertions::assertSame($post, Post::first());
45+
}
46+
47+
/**
48+
* @test
49+
* @dataProvider hundredTimes
50+
*/
51+
public function it_can_validate_relationship(): void
52+
{
53+
$post = Post::create([
54+
'title' => self::randomString(),
55+
]);
56+
57+
$comment = Comment::create([
58+
'message' => self::randomString(),
59+
'post_id' => $post->getKey(),
60+
]);
61+
62+
ModelAssertions::assertRelated($post, 'comments', Comment::class);
63+
ModelAssertions::assertRelated($post, 'comments', $comment);
64+
65+
ModelAssertions::assertRelated($post, 'comments', Comment::class, HasMany::class);
66+
ModelAssertions::assertRelated($post, 'comments', $comment, HasMany::class);
5067

51-
$model->title = self::randomString();
52-
$model->save();
68+
ModelAssertions::assertRelated($comment, 'post', Post::class);
69+
ModelAssertions::assertRelated($comment, 'post', $post);
5370

54-
ModelAssertions::assertSame($model, $model->query()->first());
71+
ModelAssertions::assertRelated($comment, 'post', Post::class, BelongsTo::class);
72+
ModelAssertions::assertRelated($comment, 'post', $post, BelongsTo::class);
5573
}
5674
}

tests/Laravel/Models/Comment.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Astrotomic\PhpunitAssertions\Tests\Laravel\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
7+
use Illuminate\Database\Schema\Blueprint;
8+
use Illuminate\Support\Facades\Schema;
9+
10+
class Comment extends Model
11+
{
12+
protected $table = 'comments';
13+
protected $guarded = [];
14+
15+
public static function migrate(): void
16+
{
17+
Schema::create((new self)->table, static function (Blueprint $table): void {
18+
$table->increments('id');
19+
$table->text('message');
20+
$table->foreignId('post_id')->constrained('posts');
21+
$table->timestamps();
22+
});
23+
}
24+
25+
public function post(): BelongsTo
26+
{
27+
return $this->belongsTo(Post::class);
28+
}
29+
}

tests/Laravel/Models/Post.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Astrotomic\PhpunitAssertions\Tests\Laravel\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Database\Eloquent\Relations\HasMany;
7+
use Illuminate\Database\Schema\Blueprint;
8+
use Illuminate\Support\Facades\Schema;
9+
10+
class Post extends Model
11+
{
12+
protected $table = 'posts';
13+
protected $guarded = [];
14+
15+
public static function migrate(): void
16+
{
17+
Schema::create((new self)->table, static function (Blueprint $table): void {
18+
$table->increments('id');
19+
$table->string('title');
20+
$table->timestamps();
21+
});
22+
}
23+
24+
public function comments(): HasMany
25+
{
26+
return $this->hasMany(Comment::class);
27+
}
28+
}

0 commit comments

Comments
 (0)