Lessons Learnt: Confident Laravel

Martin Betz • June 8, 2020

I took the course Confident Laravel when I was on vacation. It is suitable for total testing beginners.

Here are my takeaways in the format of question and answer. They are sorted by occurence in the course but you can use whatever you need for your application and testing – not everything is related to testing:

How to create a basic PHPUnit test (= extend test case)?

class PHPUnit extends TestCase
{
  public function testAssertions() 
  {
    $this->assertTrue(true);
  }
}

What are the testing definitions?

What is the order of loading test settings

  1. .env
  2. .env.testing
  3. phpunit.xml
  4. system environment variables

How to make stuff available to all tests?

Add it to tests/TestCase.php

When and why should I use PHPUnit\Framework\TestCase directly?

How to structure tests in the feature folder?

Just mimic the app folder

How to name Dusk (= BDD) tests?

How to customize Dusk's settings?

How to generate tests with subfolders?

How to name factories?

public function() {
  return $this;

}

How to filter php artisan route:list for entries containing invoice?

How to test whether the right view gets loaded?

What is the happy path?

How to check in controller if column expired with timestamp is not set?

How to put sth like a coupon in the session cookie?

How to name general controller tests?

How to check whether data exists in a session?

How to get the full error message in Laravel tests?

How many sad paths should you test?

How to assert that sth is not in a session?

What's the running order in a test?

How to mark test incomplete so it gets skipped when running the test suite?

How to test that user is logged in (and not redirected)?

How to assert that a view has a variable now_playing with value 1?

How to fake a heading or title?

How to fake an ID?

How to assert the model data you already have in your test?

How to add $faker to your test?

How to create a password hash?

How to assert two hashes?

What is the difference between asserting Hash::check() and hardcoding a password value?

How to check if session contains error 'name'?

Why do form requests not auto redirect back and how to work around that?

How to avoid writing dozens of assertions in form validations?

<?php

// In test method
$this->assertActionUsesFormRequest(
  UsersController::class, // Controller
  'update', // Method
  UserUpdateRequest::class); // Form Request
);

How to find incomplete tests?

How to directly assert non-auth cannot access?

How to manually set response 'forbidden' on controller?

How to get Product::STARTER?

What is a mock?

// What is the simplest mock you can create?
class ExampleTest extends \PHPUnit\Framework\TestCase
{
  public function testMocking()
  {
    $mock = \Mockery::mock();
    $mock->shouldReceive('foo') // method name
      ->with('bar') // arg
      ->andReturn('baz'); // arg
    $this->assertEquals('baz', $mock->foo('bar'));
  }
}

What are mocks great for?

When will mocks fail?

What is a spy?

What's the easiest spy you can write?

public function testSpying()
{
  $spy = Mockery::spy();
  $this->assertNull($spy->quix());

  // assert behavior
  $spy->shouldHaveReceived('quix')->once();
}

What are test doubles?

Why are facades easy to test in Laravel?

How to return nothing (do nothing after a request)?

return response(null, 204)

How to mock Laravel's Log facade?

$mock = \Mockery::mock();
$mock->shouldReceive('info') // method name
  ->once()
  ->with('video.watched', [$video->id]);
Log::swap($mock);

What is the difficulty with shared facades?

What to do instead of mocks?

What happens in this mock?

Why do I need the Log:: facade at all?

Why do you use ->once() in a mock?

What is a shortcut for $mock->shouldReceive('info')->once()?

How to create a setup method that runs for all tests in a file?

protected function setUp(): void
{
  parent::setUp();
  $this->subject = new UserUpdateRequest();
}

Use it with $this->subject in the tests

How to run a validation in an unit test?

$subject = new UserUpdateRequest();
// will call the file App\Http\Requests\UserUpdateRequest;

How to create a coverage report