Testing Laravel FormRequest classes

Image for post
Image for post
testing for requests using FormRequestTester Package

I always deal with controllers as a glue for my applications and never done any logic inside them, including Validation & Authorization logic.
Laravel FormRequest classes have helped me a lot with keeping my controllers as a glue, but I always found them very hard to be tested. By surfing the web I found two ways to test them and also worked to create my own way, so in this blog post, I’m gonna demonstrate three ways to test Laravel FormRequests.

Before diving in:

before doing any work we need a FormRequest as an example so let’s take the following into consideration.

  1. we need to update a post fields: title, content.
  2. both fields are required, plus, content should have more that 300 characters (min:300)
  3. posts/{post} using put http method, is the route used to update the post.
  4. and the following class is the FormRequest the we’ll use to explain the three ideas.

Idea #1: Creating your own validator:

This way is very simple and intuitive, simply, you create your own validator and inject your rules and messages inside the validator, like the following

Pros:

  1. It’s simple: pretty much, It’s the first thing you’ll think of when start testing your FormRequests.

Cons:

  1. things will get harder as you’re making assertions for what fields have failed and what are the messages returned.
  2. testing authorization is very hard, especially when you’re using $this->route('post') method in your authorization logic.
  3. things that are related to your FormRequest can’t be tested this way like prepareForValidation

one way to overcome the authorization problem is to add the ability to pass the model to authorize method, but I'm not a fan of adding a piece of code to the logic just to improve testing.

Idea #2: sending real requests:

The second approach is sending a real request to the route where the FormRequest will be instantiated and then see what’s the response and act accordingly.

Pros:

  1. It’s an integration test.

Cons:

  1. It’s an Integration test: meaning that you have to make sure everything is working in the controller where FormRequest is instantiated because the simplest error will throw an exception.
  2. you have to send two real requests if you want to test another rule for the same field. ex: you need to send content with your request to make sure that min:300 rule is working.
  3. makes your tests slower: because you need to start your whole application with each test.

Idea #3: Using FormRequestTester package:

this package will mock the needed part of your application and reuse them without the need to start your whole application on every test.

Pros:

  1. It’s simple: It provides simple and intuitive methods.
  2. It’s a unit test, not an integration test: for me, I don’t use integration tests to make sure that one thing works fine, I only use it to make sure that all classes in my app work well with each other.
  3. It allows you to test validation, authorization, and other related topics.

Cons:

As I’m the developer of the package, I can’t find a con for it, but if you have one please notify me via email or comments and I promise to add it here.

Final Words:

I say every programmer should be pragmatic, please choose the best way that suits you and your team best.

Written by

A Passionate Full-Stack developer who loves to turn great ideas into elegant products

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store