简体   繁体   中英

When running unit tests with laravel, how do you test your App::error() implementations?

I'm currently working on an open source personal project that provides a nice backend api for game developers. I'm in the early stages of development, but I plan to write tests as I go along, which is where I've hit a snag.

Through out the system when an error occurs such as incorrect api credentials or missing credentials, I throw a custom exception which stores a bit of extra data so that I can catch it and give a JSON encoded response.

The tests work fine for those thrown in my BaseController, but I also capture a few Laravel Exceptions so I can respond with my own, or at least, output JSON like below:

app/start/global.php

App::error(function(Exception $exception, $code) {
    Log::error($exception);
});

App::missing(function(Exception $exception) {
    return BaseController::error(
            Config::get('response.method.code'), 
            Config::get('response.method.http'), 
            'Method not found'
    );
});

App::error(function(Viper\Exception $exception) {
    return BaseController::error(
            $exception->getCode(), 
            $exception->getStatusCode(), 
            $exception->getMessage()
    );
});

I'm using the try { } catch() { } approach as I need to check an extra value that isn't in the normal Exceptions.

public function testNoMethodGET() {
    $config = Config::get('response.method');

    try {
        $this->call('GET', '/');
    } catch(\Viper\Exception $e) {
        $this->assertEquals($e->getCode(), $config['code']);
        $this->assertEquals($e->getStatusCode(), $config['http']);
    }

    $this->fail('Exception not thrown');
}

This is all good and well, but I want to check a few things on the actual response, like for example, whether or not the json is valid, whether or not the response structure matches and whether or not the response values are correct.

If I set the return value of $this->call() to a variable, I'd be unable to access that variable within the catch block, so the question is this, how can I test the return value of $this->call() once the Exception has been caught?

According to Taylor Otwell:

"this can be solved by de-coupling your test. You really want to test the handler and that the exception is thrown totally separately anyways [sic] to isolate your tests. For instance:

App::error(function(ErrorType $e)
{
     App::make('ErrorTypeHandler')->handle($e);
});

Now you can write test cases for ErrorTypeHandler class separately from the rest of your application. Then check that proper exceptions are thrown by your app with @expectedException."

In your case, you already have isolated your error handler in BaseController::error(), so you can test the responses directly in separate unit tests, without the use of $this->call(). Instead, just call $response = BaseController::error() with the desired parameters and then inspect the response and apply relevant assertions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM