Back to Course |
Testing in Laravel 11: Advanced Level

Testing Strings: Expect toContain

Now, I will show a few assertions related to text data to check something within a string. We will look at the examples from open-source projects.


Pest and PHPUnit Syntax Differences

In this course, we're trying to cover both tools. String assertion is the (rare) case when the syntax is slightly different.

The assertStringStartsWith() and other similar string assertions are for PHPUnit. We will look at those examples later in the lesson.

With Pest, you would use expectations with equivalent methods. For example, an equivalent to the assertStringContainsString() method in Pest would be toContain().


Laravel.io Example: Look for a Phrase in Email

In the open-source example from a laravelio/laravel.io project, we can see how toContain() is used to check if an email text contains certain phrases.

The second test method checks if the email does NOT contain a specific text.

tests/Integration/Mail/NewReplyEmailTest.php:

use App\Mail\NewReplyEmail;
use App\Models\Reply;
use App\Models\Subscription;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;
 
uses(TestCase::class);
uses(DatabaseMigrations::class);
 
it('contains a note about solutions when the receiver is the thread author', function () {
$reply = Reply::factory()->create();
$thread = $reply->replyAble();
$subscription = Subscription::factory()->create(['subscriptionable_id' => $thread->id]);
 
$email = (new NewReplyEmail($reply, $subscription, $thread->author()))->render();
 
expect($email)
->toContain('Please make sure to mark the correct reply as the solution when your question gets answered.');
});
 
it('misses the note about solutions when the receiver is not the thread author', function () {
$reply = Reply::factory()->create();
$thread = $reply->replyAble();
$user = User::factory()->create();
$subscription = Subscription::factory()->create(['subscriptionable_id' => $thread->id]);
 
$email = (new NewReplyEmail($reply, $subscription, $user))->render();
 
expect($email)->not
->toContain('Please make sure to mark the correct reply as the solution when your question gets answered.');
});

See the elegant readable syntax of Pest? It sounds almost like the English language: "Expect email text not to contain XYZ".


Larastreamers Example: Check the Beginning Text

The second example is from an open-source project christophrumpel/larastreamers. In this test, the author uses the expectation toStartWith(), equivalent to the assertStringStartsWith() from PHPUnit.

tests/Unit/YouTubeTest.php:

use App\Facades\YouTube;
use App\Services\YouTube\StreamData;
use Illuminate\Support\Facades\Http;
 
it('can fetch channel details from youtube', function() {
// Arrange
Http::fake(fn () => Http::response($this->channelResponse()));
 
// Act
$channel = YouTube::channel('UCdtd5QYBx9MUVXHm7qgEpxA');
 
// Assert
expect($channel)
->youTubeCustomUrl->toBe('christophrumpel')
->name->toBe('Christoph Rumpel')
->description->toStartWith('Hi, I\'m Christoph Rumpel')
->onPlatformSince->toIso8601String()->toBe('2010-01-12T19:15:29+00:00')
->country->toBe('AT')
->thumbnailUrl->toBe('https://yt3.ggpht.com/ytc/AAUvwniFZUkXnS4vDKY4lDohrpFsyu1V2AJwt4CFZGy25Q=s800-c-k-c0x00ffffff-no-rj');
});
 
// ...

PHPUnit Examples

AssertStringStartsWith()

The first example is from a monicahq/monica project. Here, an assertion is made to check if the returned URL for the wallpaper starts with the APP_URL.

tests/Unit/Helpers/WallpaperHelperTest.php:

use App\Helpers\WallpaperHelper;
use Tests\TestCase;
 
class WallpaperHelperTest extends TestCase
{
/** @test */
public function it_returns_a_random_wallpaper(): void
{
$this->assertStringStartsWith(
env('APP_URL').'/',
WallpaperHelper::getRandomWallpaper()
);
}
}

Another example is from the koel/koel open-source project. The check is made here if the returned string starts with the gravatar link.

tests/Integration/Services/UserServiceTest.php:

class UserServiceTest extends TestCase
{
// ...
 
public function testCreateUserWithEmptyAvatarHasGravatar(): void
{
$user = $this->service->createUser(
name: 'Bruce Dickinson',
email: 'bruce@dickison.com',
plainTextPassword: 'FearOfTheDark',
isAdmin: false
);
 
self::assertModelExists($user);
self::assertTrue(Hash::check('FearOfTheDark', $user->password));
self::assertFalse($user->is_admin);
self::assertStringStartsWith('https://www.gravatar.com/avatar/', $user->avatar);
}
 
// ...
}

AssertStringContainsString()

This example is from the koel/koel open-source project. The method's name is straightforward: it checks if one string contains another.

tests/Integration/KoelPlus/Services/SongStorages/S3CompatibleStorageTest.php:

class S3CompatibleStorageTest extends PlusTestCase
{
// ...
 
public function testGetPresignedUrl(): void
{
Storage::fake('s3');
 
$song = $this->service->storeUploadedFile($this->file, create_user());
$url = $this->service->getSongPresignedUrl($song);
 
self::assertStringContainsString($song->storage_metadata->getPath(), $url);
}
}

The second example of the same method is from Kovah/LinkAce open-source project.

tests/Components/HistoryEntryTest.php:

class HistoryEntryTest extends TestCase
{
// ...
 
public function testAddedChange(): void
{
$link = Link::factory()->create([
'description' => null,
]);
 
$link->description = 'Test Description';
$link->save();
 
$historyEntry = $link->revisionHistory()->first();
 
$output = (new HistoryEntry($historyEntry))->render();
 
$this->assertStringContainsString('Added <code>Test Description</code> to Description', $output);
}
 
// ...
}