cerberuspup's avatar

Test not failing

I've created a unit test that posts to a route, the issue I think I'm having is that the tests passed even though it should fail.

This is my code

$user = User::factory()->create();
$this->actingAs($user);

$response = $this->json('post', '/api/admin/products/create', [
    'name' => null
]);

$this->assertEquals(200, $response->getStatusCode());
0 likes
10 replies
tykus's avatar

It should fail because there is a validation rule?

Can you dump the response to see what you are getting?

$response = $this->json('post', '/api/admin/products/create', [
    'name' => null
]);
$response->dump();
tykus's avatar

@cerberuspup dump the $response - perhaps you going to get something that will reveal the cause.

cerberuspup's avatar

@tykus here it is

Illuminate\Testing\TestResponse^ {#4960
  +baseResponse: Illuminate\Http\RedirectResponse^ {#2616
    #request: Illuminate\Http\Request^ {#2509
      #json: Symfony\Component\HttpFoundation\ParameterBag^ {#2504
        #parameters: array:1 [
          "name" => null
        ]
      }
      #convertedFiles: null
      #userResolver: Closure($guard = null)^ {#2500
        class: "Illuminate\Auth\AuthServiceProvider"
        this: Illuminate\Auth\AuthServiceProvider {#4958 …}
        use: {
          $app: Illuminate\Foundation\Application {#3498 …}
        }
        file: "./vendor/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php"
        line: "105 to 107"
      }
      #routeResolver: Closure()^ {#2522
        class: "Illuminate\Routing\Router"
        this: Illuminate\Routing\Router {#1315 …}
        use: {
          $route: Illuminate\Routing\Route {#1294 …}
        }
        file: "./vendor/laravel/framework/src/Illuminate/Routing/Router.php"
        line: "655 to 657"
      }
      +attributes: Symfony\Component\HttpFoundation\ParameterBag^ {#2511
        #parameters: []
      }
      +request: Symfony\Component\HttpFoundation\ParameterBag^ {#2504}
      +query: Symfony\Component\HttpFoundation\InputBag^ {#2517
        #parameters: []
      }
      +server: Symfony\Component\HttpFoundation\ServerBag^ {#2513
        #parameters: array:19 [
          "SERVER_NAME" => "localhost"
          "SERVER_PORT" => 80
          "HTTP_HOST" => "localhost"
          "HTTP_USER_AGENT" => "Symfony"
          "HTTP_ACCEPT" => "application/json"
          "HTTP_ACCEPT_LANGUAGE" => "en-us,en;q=0.5"
          "HTTP_ACCEPT_CHARSET" => "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
          "REMOTE_ADDR" => "127.0.0.1"
          "SCRIPT_NAME" => ""
          "SCRIPT_FILENAME" => ""
          "SERVER_PROTOCOL" => "HTTP/1.1"
          "REQUEST_TIME" => 1635915055
          "REQUEST_TIME_FLOAT" => 1635915055.9512
          "HTTP_CONTENT_LENGTH" => 13
          "CONTENT_TYPE" => "application/json"
          "PATH_INFO" => ""
          "REQUEST_METHOD" => "POST"
          "REQUEST_URI" => "/api/admin/products/create"
          "QUERY_STRING" => ""
        ]
      }
      +files: Symfony\Component\HttpFoundation\FileBag^ {#2514
        #parameters: []
      }
      +cookies: Symfony\Component\HttpFoundation\InputBag^ {#2512
        #parameters: []
      }
      +headers: Symfony\Component\HttpFoundation\HeaderBag^ {#2515
        #headers: array:7 [
          "host" => array:1 [
            0 => "localhost"
          ]
          "user-agent" => array:1 [
            0 => "Symfony"
          ]
          "accept" => array:1 [
            0 => "application/json"
          ]
          "accept-language" => array:1 [
            0 => "en-us,en;q=0.5"
          ]
          "accept-charset" => array:1 [
            0 => "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
          ]
          "content-length" => array:1 [
            0 => 13
          ]
          "content-type" => array:1 [
            0 => "application/json"
          ]
        ]
        #cacheControl: []
      }
      #content: "{"name":null}"
      #languages: null
      #charsets: null
      #encodings: null
      #acceptableContentTypes: array:1 [
        0 => "application/json"
      ]
      #pathInfo: "/api/admin/products/create"
      #requestUri: "/api/admin/products/create"
      #baseUrl: ""
      #basePath: null
      #method: "POST"
      #format: null
      #session: null
      #locale: null
      #defaultLocale: "en"
      -preferredFormat: null
      -isHostValid: true
      -isForwardedValid: true
      -isSafeContentPreferred: null
      basePath: ""
      format: "html"
    }
    #session: Illuminate\Session\Store^ {#2486
      #id: "UfsJMnQttHwkZZGXBCtkCizVjRNAPr3BDteRqAfx"
      #name: "laravel_session"
      #attributes: []
      #handler: Illuminate\Session\ArraySessionHandler^ {#2499
        #storage: []
        #minutes: "120"
      }
      #started: false
    }
    #targetUrl: "http://localhost"
    +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag^ {#2630
      #computedCacheControl: array:2 [
        "no-cache" => true
        "private" => true
      ]
      #cookies: []
      #headerNames: array:4 [
        "cache-control" => "Cache-Control"
        "date" => "Date"
        "location" => "Location"
        "content-type" => "Content-Type"
      ]
      #headers: array:4 [
        "cache-control" => array:1 [
          0 => "no-cache, private"
        ]
        "date" => array:1 [
          0 => "Wed, 03 Nov 2021 04:50:55 GMT"
        ]
        "location" => array:1 [
          0 => "http://localhost"
        ]
        "content-type" => array:1 [
          0 => "text/html; charset=UTF-8"
        ]
      ]
      #cacheControl: []
    }
    #content: """
      <!DOCTYPE html>\n
      <html>\n
          <head>\n
              <meta charset="UTF-8" />\n
              <meta http-equiv="refresh" content="0;url='http://localhost'" />\n
      \n
              <title>Redirecting to http://localhost</title>\n
          </head>\n
          <body>\n
              Redirecting to <a href="http://localhost">http://localhost</a>.\n
          </body>\n
      </html>
      """
    #version: "1.1"
    #statusCode: 302
    #statusText: "Found"
    #charset: null
    +original: null
    +exception: null
  }
  #streamedContent: null
}
tykus's avatar

@cerberuspup

Whenever you return from the validation failure, you will get a 200 response status code because you do not explicitly set an appropriate status code; you can change that behaviour here:

if($validate->fails())
{
    return response()->json([
        'error' => true,
        'errorMsg' => $validate->errors()
    ], 422);
}

From the response dump, you can see that your request is being redirected; which is an odd Response status for an API endpoint; generally an API will respond with 2xx and 4xx status codes only. Do you return a Redirect in any circumstance in your application code (e.g. a middleware)???

Otherwise, there is another exception being handled by the framework; if you disable exception handling temporarily you should get an exception stacktrace; post that here:

$this->withoutExceptionHandling();
$user = User::factory()->create();
$this->actingAs($user);

$response = $this->json('post', '/api/admin/products/create', [
    'name' => null
]);

$this->assertEquals(200, $response->getStatusCode());
Sinnbeck's avatar

Or show the controller code so we can see what it is actually doing

cerberuspup's avatar

@Sinnbeck here it is

$validate = Validator::make(request()->all(), [
    "name" => "required",
]);

if($validate->fails())
{
    return [
        'error' => true,
        'errorMsg' => $validate->errors()
    ];
}

$product = Product::create([
    'name' => trim(request('name'))
]);


return [
    'product' => $product
];
Tray2's avatar

I've noticed that sometimes tests pass even though the shouldn't and that is usually solved with adding

$this->withoutExceptionHandling();

To your test and when it passed/fails when it should remove the line.

cerberuspup's avatar

@Tray2 I think I did what you suggested correctly, but whether or not a set the name to null or if I give it a string I still get This test did not perform any assertions

Tray2's avatar

@cerberuspup Try adding at the top of your test.

$this->assertTrue(true); 

Then run it again just to see if the message goes away.

Please or to participate in this conversation.