orest's avatar
Level 13

Integration or unit test

It is not quite clear to me when I should use integrations and unit test

If I want to test the following code without making any http requests, should I use an integration test or unit ?

When a thread is created, the activity is recorded and an email event is fired

ThreadObserver extends Observer
{
    public function created(Thread $thread)
    {
        Activity::record($thead);
        event(new ThreadWasCreated($thread);
     }
}
class RecordsActivityTest
{
    public function it_records_the_acitivty_when_a_thread_is_created()
    {
        Thread::factory()->create();
        $this->assertDatabaseHas('activities', […]);
   
    }
    

}

Another example, I want to test that give a query it returns the expected results .

class Search
{
     public function __construct(protected Index $index)
     {
            
      }

      public function handle($query)
      {
            $this->index->search($query);
             // more code 
       }
}
class SearchTest
{
    public function it_returns_the_expected_result()
    {
        $search = new Search(new Index);
        $results = $search->handle(“some query”);
        $this->assertEquals(“some
    Data”);
    }

}


Do I need a unit test, to test the Search class or an integration test because it is dependent on another class ?

0 likes
3 replies
tylernathanreed's avatar

Generally speaking, I use Unit tests to cover a specific class, and I name the test after the class in question.

If the class in question relies on external classes, I try to mock those, so that I'm only testing the core of the class in question.

However, when it comes to integration tests, I care about the end-to-end result. This typically means faking a request, job, or command, and ensure that at the end of the entire process, I have the expected end result. I do little to no mocking on these.

1 like
martinbean's avatar

When a thread is created, the activity is recorded and an email event is fired

@orest Then that’s very much an integration test. You‘re not testing a single unit of code there; you’re testing multiple things (thread being created, activity being recorded, an email being queued/sent).

A unit test is a test that tests a single piece of code in isolation, i.e. a method where you pass a method some parameters and assert the result. If that method touches anything outside (the Laravel framework, a database, queues, emails, etc) then it’s no longer a unit test.

1 like
orest's avatar
Level 13

@martinbean

Taking the second example with the Search. The handle method uses the Index class, and this is why it is no longer a unit test but an integration test, right ?

Does the same thing hold when testing relationships ?

If you want to determine that a relationship method returns the expected result, it is considered an integration test again ?

Please or to participate in this conversation.