PHPUnit - AssertCount 在有多个插入方法时失败

PHPUnit - AssertCount fails when having multiple insertion methods

嘿,我刚开始使用 PHPUnit。我正在尝试测试将模型(称为 Actor)插入到数据库中。创建此模型会导致创建其他模型(如 SubactorContact)。为此,我单独测试了每个模型的创建。

问题是,当我尝试 运行 单独进行每个测试时,一切正常。但是,当我尝试 运行 整个 class 测试时。 AssertCount 方法失败,因为每个方法都会添加一个模型,因此计数会增加,并且在 运行 整个 class 测试时数据库不会刷新。

我尝试在每个方法的开头初始化每个模型的计数,但我认为这不是最佳解决方案。

有人能帮忙吗?

谢谢!

class ActorTest extends TestCase
{
    use WithFaker;
    use RefreshDatabase;

    
    /** @test */
    public function an_actor_can_be_added()
    {
        $user = factory(Admin::class)->create();

        $response = $this->actingAs($user)
        ->post('admin/actor',
        array_merge(factory(Actor::class)->make()->toArray(),
        ['contact'=>[factory(Contact::class)->make()->toArray()]]));
        
        $this->assertCount(1, Actor::all());
    }

    /** @test */
    public function a_subactor_is_added_when_actor_created(){
        $user = factory(Admin::class)->create();

        $this->actingAs($user)
        ->post('admin/actor',
        array_merge(factory(Actor::class)->make()->toArray(),
        ['contact'=>[factory(Contact::class)->make()->toArray()]]));

        $this->assertCount(1, Subactor::all());
    }

    /** @test */
    public function a_contact_is_added_when_actor_created(){
        $user = factory(Admin::class)->create();

        $this->actingAs($user)
        ->post('admin/actor',
        array_merge(factory(Actor::class)->make()->toArray(),
        ['contact'=>[factory(Contact::class)->make()->toArray()]]));

        $this->assertCount(1, Contact::all());
    }

    /** @test */
    public function an_actor_is_linked_to_subactor_when_created(){
        $user = factory(Admin::class)->create();

        $this->actingAs($user)
        ->post('admin/actor',
        array_merge(factory(Actor::class)->make()->toArray(),
        ['contact'=>[factory(Contact::class)->make()->toArray()]]));

        $actor = Actor::first();
        $subactor = Subactor::first();
        
        $this->assertEquals($actor->id, $subactor->actor_id); 
    }

    /** @test */
    public function a_subactor_is_linked_to_contact_when_created(){
        $user = factory(Admin::class)->create();

        $this->actingAs($user)
        ->post('admin/actor',
        array_merge(factory(Actor::class)->make()->toArray(),
        ['contact'=>[factory(Contact::class)->make()->toArray()]]));

        $subactor = Subactor::first();
        $contact = Contact::first();
        
        $this->assertEquals($subactor->id, $contact->subactor_id); 
    }
}

您正在测试的代码广泛使用全局状态(通过静态方法),这就是您的测试相互干扰的原因。为避免在每个方法中重置状态,您可以使用带有 @before 注释的方法或覆盖测试用例 class 的 setUp() 方法 - 这些代码将在每次测试之前执行方法。

我不知道这是否是正确的解决方案,但我这样做了。

protected function tearDown(): void
     {
         Actor::truncate();
         Subactor::truncate();
         Contact::truncate();
     }