0

I have two test classes Tests\Unit\BlogTest and Tests\Feature\BlogTest. In Tests\Unit\BlogTest, the response should be 422, which is obviously not good for redirection.

Below is BlogController -> Create() method code:

if ($validator->fails()) {
  if (app()->runningUnitTests()) {
    return response('Validation failed', 422);
  }
  return redirect()->route('blog_edit', ['id' => $id])
    ->withErrors($validator)
    ->withInput();
}

Below code is from Tests\Unit\BlogTest

public function test_blog_create_validation()
{
    $reqData = ['title' => null, 'author' => null, 'content' => null];
    $response = $this->postJson(
        action([BlogController::class, 'create']),
        $reqData
    )->assertStatus(422);
}

Below code is from Tests\Feature\BlogTest

public function test_blog_create_validation()
{
    $response = $this->post('/blog', [
        'title'   => '',
        'author'  => '',
        'content' => ''
    ]);
    
    $response->assertSessionHasErrors([
        'title',
        'author',
        'content'
    ]);
}

Now, the problem is, app()->runningUnitTests()) condition satisfy unit test, without this condition, it satisfy feature test. See below images for the reference:

  1. Feature test passed without condition, but unit test failed
  2. Unit test passed with condition but feature test failed

Feature test passed without condition, but unit test failed

Unit test passed with condition but feature test failed

Question: How to satisfy both Unit and Feature tests?

Haroon
  • 155
  • 2
  • 10
  • 2
    Usually, your controller code should not contain any checks for running tests. Why do you want to use a different response in your tests, and not exactly the one you usually send to the browser? – Nico Haase May 29 '23 at 13:00
  • @NicoHaase Actually these test files came from TestGorilla and I was trying to get 100% results which those test cases. If I don't apply condition and simply redirect back with validation error, the 422 HTTP code not satisfy because 422 is not for redirection. – Haroon Jun 11 '23 at 05:58
  • 1
    @Haroon so, you must NOT add different code in your controller to satisfy a tests response or resolution. The test MUST literally test the code you have in there, without the original code doing any change when it is running tests... You have to use the included Laravel's stuff, for example, you have to use [`$this->assertSessionHasErrors(...)`](https://laravel.com/docs/10.x/http-tests#assert-session-has-errors), not return a specific string and look for `422`... Check out my SO profile, you have answers there that will help you exactly with this issue – matiaslauriti Jul 24 '23 at 14:14
  • Does this answer your question? [Unit Test Laravel's FormRequest](https://stackoverflow.com/questions/36978147/unit-test-laravels-formrequest) – matiaslauriti Jul 24 '23 at 14:14

0 Answers0