我正在使用Laravel为
IOS应用程序构建API.我正在遇到使用
PHPUnit和内置Laravel测试来测试Web应用程序的主要问题.
我的流程是1.用户拥有帐户2.用户需要通过身份验证才能执行任何操作.
假设我有一组用户,并且一个用户(所有者)可以管理属于其中一个组的成员.我想测试用户将其他成员添加到他们的组的能力.
我有一个名为testAddGroupMemberPass()的测试方法
>创建用户(所有者)
>创建一个组并分配所有者
>创建要添加到组的用户
>断言所有者有能力添加该成员.
public function testAddGroupMemberPass() { // 1. create owner $owner = factory(User::class)->create(); $token = JWTAuth::fromUser($owner); // 2. create group and attach user $group = new Group; $group->owner_id = $owner->id; $group->save(); // 3. create the member to be $user = factory(User::class)->create(); // 4. attempt attach the member to the group $this->edit('/groups/' . $group->id . '/add-member/' . $user->username . '?token=' . $token) ->seeJson(['success' => true]); }
要声明所有者可以添加用户,您必须先创建所有者,然后创建该组,第三步创建要添加到该组的用户,最后您可以尝试向API发出请求实际添加该用户.
问题是在前3个步骤中可能遇到的各种问题与向组添加成员的过程完全无关,例如用户名和电子邮件唯一约束.
那么我目前的做法有什么问题?我总是被告知测试应该完全相互独立,因此尝试使用先前测试AFAIK生成的用户和组是没有意义的.
解决方法
您可以将1,2和3抽象为基础测试类,并将这些相同的方法用于测试这些特定功能的测试.
例如:
// TestCase.PHP protected function createOwner() { return factory(User::class)->create(); } protected function createGroup($owner) { // You didn't show this as a factory,but I figured you might want that $group = factory(Group::class)->create(); $group->owner()->associate($owner); $group->save(); return $group; } protected function createUser() { return factory(User::class)->create(); } // In the file you mention above (should be extending TestCase.PHP) public function testAddGroupMemberPass() { // 1. create owner $owner = $this->createOwner(); $token = JWTAuth::fromUser($owner); // 2. create group and attach user $group = $this->createGroup($owner); // 3. create the member to be $user = $this->createUser(); // 4. attempt attach the member to the group $this->edit('/groups/' . $group->id . '/add-member/' . $user->username . '?token=' . $token) ->seeJson(['success' => true]); }
这些方法可以用于其他测试,如下所示:
// In UserTest.PHP (also extends TestCase.PHP) public function testItCreatesAUser() { $user = $this->createUser(); $this->seeInDatabase('users',$user); }
事实是,如果你需要你的世界看起来某种方式并且你正在做某种功能或集成测试,那么你需要在某个地方封装那个逻辑.将其移动到基类将有助于删除重复的功能.