ohffs/scenarios

轻松创建针对特定测试场景的数据库助手

dev-master 2017-06-08 15:12 UTC

This package is auto-updated.

Last update: 2024-09-22 02:53:36 UTC


README

这是一个非常基础的PHP类和特性,用于简化“场景”的使用。最初它是为Laravel phpunit测试编写的,但理论上它可以用于其他用途。

什么是...“场景”?

在编写测试时,我经常发现自己需要在每个测试中重复做类似的事情

$admin = factory(User::class)->states('admin')->create();
$user = factory(User::class)->states('regular')->create();
$post = factory(Post::class, 3)->states('unpublished')->create(['user_id' => $user->id]);
...

这段代码可能在十几个测试中重复。因此,有时我会写一个辅助函数——有时不会,因为直接从上一个测试中复制粘贴代码更快。所以我决定写一个非常简单的辅助工具,它基本上是一个键/值存储,这样我就可以在测试中做一些更具有表现力的操作,如下所示

$this->scenarios()->playout('there is an admin and a user with three posts');

用法

假设你想使用这个特性

class SomeTest {

    use \Ohffs\Scenarios\HasScenarios;

    public function setUp()
    {
        parent::setUp();
        $this->scenarios()->write('there is an unpublished post and an admin', function ($params) {
            $admin = factory(User::class)->states('admin')->create();
            $post = factory(Post::class)->states('unpublished')->create($params);
            return [$admin, $post];
        });
        $this->scenarios()->write('we have a published post', function () {
            return factory(Post::class)->states('published')->create();
        });
        $this->scenarios()->write('we have an admin', function () {
            return factory(User::class)->states('admin')->create();
        });
        $this->scenarios()->write('we have a regular user', function () {
            return factory(User::class)->states('regular')->create();
        });
    }

    public function test_an_admin_can_mark_a_post_as_published()
    {
        [$admin, $post] = $this->scenarios()
                            ->playout('there is an unpublished post and an admin', ['title' => 'A Post Title'])
                            ->andReturnResults();

        $response = $this->actingAs($admin)->post('/posts/' . $post->id, ['status' => 'published']);

        $this->assertEquals(1, Post::published()->count());
    }

    public function test_an_admin_can_delete_a_post()
    {
        [$admin, $post] = $this->scenarios()->playout('there is an unpublished post and an admin')->andReturnResults();

        $response = $this->actingAs($admin)->delete('/posts/' . $post->id);

        $this->assertEquals(0, Post::count());
    }


    public function test_a_user_cant_delete_posts_that_are_not_theirs()
    {
        [$post, $badUser] = $this->scenarios()
                                ->playout('we have a published post')
                                ->andAlso('we have a regular user')
                                ->andReturnResults();

        $response = $this->actingAs($badUser)->delete('/posts/' . $post->id);

        $response->assertStatus(302);
        $this->assertEquals(1, Post::count());
    }
}

注意

如果你尝试“模拟”一个不存在的场景,代码将抛出\InvalidArgumentException异常。

如果你的场景列表只调用一个“东西”,那么它将原样返回,否则它将返回一个包含这些“东西”的数组。例如。

$this->scenarios()->write('we have a regular user', function () {
    return ['username' => 'jenny', 'status' => 'normal'];
});
$this->scenarios()->write('we have a super user', function () {
    return ['username' => 'marlene', 'status' => 'admin'];
});

$admin = $this->scenarios()->playout('we have a super user')->andReturnResults();
$user = $this->scenarios()->playout('we have a regular user')->andReturnResults();
[$user, $admin] = $this->scenarios()->playout('we have a regular user')->andAlso('we have a super user')->andReturnResults();