logo
podcast Podcast
get help Get Unstuck

A technique for testing legacy code

Which is seldom well-behaved

Joel Clermont
Joel Clermont
2024-08-21

Testing in Laravel is so easy, sometimes we forget how tricky it can be to test code that isn't well-behaved.

For example, let's say an application is using the older MPDF library to generate and download a PDF from inside a Laravel controller.

The expectation is that MPDF will completely manage the response, so we cannot allow Laravel to generate anything in the response. We need our controller to exit abruptly after calling OutputHttpDownload on the MPDF object.

But if you just put exit in your controller, you'll never be able to test it. PHPUnit will stop and fail when it exits early.

Here's a helper I've used in place of calling exit directly:

protected function endRequest()
{
    if (App::environment('testing')) {
        return 0;
    }

    exit;
}

Let me be clear: this is not something you should do lightly. Altering application code in service of your tests is something I typically strongly avoid. And this function should have a giant comment explaining why it exists and the only time you should use it.

But if you need to use an old-school library that makes it difficult to test, this can be a valid trade-off until you can refactor the code to use a more modern library.

Here to help,

Joel

P.S. Testing legacy code can pose challenges, but it can be done! If you need help introducing testing to your legacy project, let's chat.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice you can use.