Ad

How To Perform A Unit Test For A Backend Controller

I wish to test if my backend controllers perform properly via unit tests so I don't have to manually check them when changing things around.

Unfortunately on everything I try I get a 404 not found.

My phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="../../../tests/bootstrap.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
>
    <testsuites>
        <testsuite name="ExitControl.Administration test suite">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
    </php>
</phpunit>

The test in which i'm trying to access the backend url

public function setUp() 
{
    parent::setup();

    $user = User::create([
        'email' => '[email protected]',
        'login' => 'tester',
        'password' => 'test',
        'password_confirmation' => 'test',
        'send_invite' => false,
        'is_activated' => true,            
    ]);

    $user->is_superuser = true;
    $user->save();

    $user = BackendAuth::authenticate([
        'login' => 'tester',
        'password' => 'test'
    ], true);
}

public function testCreateIndexView()
{

    $controller = $this->getController();

    $configUrl = config('app.url') . '/' . 
                 config('cms.backendUri') . '/';

    $url = preg_replace('/([^:])(\/{2,})/', '$1/', 
            $configUrl . 
            str_replace(['controllers\\', '\\'], ['', '/'], 
            strtolower(get_class($controller))));

    $result = $this->get($url);

    dd($result);// shows a 404
}

The output of dd();

PHPUnit 5.7.27 by Sebastian Bergmann and contributors.

CreateExitcontrolAdministrationCompaniesTable > dropping table exitcontrol_administration_companies
CreateExitcontrolAdministrationCompaniesTable > creating table exitcontrol_administration_companies
Illuminate\Foundation\Testing\TestResponse {#55
  +baseResponse: Illuminate\Http\Response {#1696
    +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag {#1695
      #computedCacheControl: array:2 [
        "no-cache" => true
        "private" => true
      ]
      #cookies: array:1 [
        "" => array:1 [
          "/" => array:2 [
            "october_session" => Symfony\Component\HttpFoundation\Cookie {#1073
              #name: "october_session"
              #value: "eyJpdiI6Imh1SHlCUkhcL29rMlk2dFBkZTRNWlpnPT0iLCJ2YWx1ZSI6IjFJamxxRW9aQkM5bk9kM2VnMExLUTdVNER0MzlcL2xacFdkMCs0dTdXR1N0NVwva01KaTVwbnhVUVI2S0Q2MmRJaldWdEtyRldBcmNkc2dWMnhrVTJoZ3c9PSIsIm1hYyI6IjUyYTJiYWRlNDUzYTFjZjRhMDVhNzliMzJjNGVhZTBjNWViMDlmNTJkMWM3NjhlZGE4NTRjYjhiY2U3M2EzNmUifQ=="
              #domain: null
              #expire: 1537286593
              #path: "/"
              #secure: false
              #httpOnly: true
              -raw: false
              -sameSite: null
            }
            "admin_auth" => Symfony\Component\HttpFoundation\Cookie {#1072
              #name: "admin_auth"
              #value: "eyJpdiI6InVWM1pFNExzMytCMzZQWEJISTJoOFE9PSIsInZhbHVlIjoiU1l2NitIUDNFd3JVeHdhenh2alV5YWxtMW1vYTFsbUhweDlJd3RcL2xDQnQyY3cwMVAzOFNDQjdrQXNZS1JFUmV4U2FVWG5XV0g3d0VOYStIR2hxV25nMDNlc1wvdStma2hkYlZTV01vemg0R1FpXC80ZWQ5YjMwcjdPSW9aRnJzS1MiLCJtYWMiOiJiYWFjODE2NTBjOGQ0NjkwNmJlYzVjZjFhOTJjMjdmYzBkMTA2MDEzNTM0MTljMmE2Njc1Njc0NTlmMGQ5ZWY4In0="
              #domain: null
              #expire: 1694959389
              #path: "/"
              #secure: false
              #httpOnly: true
              -raw: false
              -sameSite: null
            }
          ]
        ]
      ]
      #headerNames: array:4 [
        "cache-control" => "Cache-Control"
        "date" => "Date"
        "content-type" => "Content-Type"
        "set-cookie" => "Set-Cookie"
      ]
      #headers: array:3 [
        "cache-control" => array:1 [
          0 => "no-cache, private"
        ]
        "date" => array:1 [
          0 => "Tue, 18 Sep 2018 14:03:13 GMT"
        ]
        "content-type" => array:1 [
          0 => "text/html; charset=UTF-8"
        ]
      ]
      #cacheControl: []
    }
    #content: "

Page not found

" #version: "1.1" #statusCode: 404 #statusText: "Not Found" #charset: null +original: "

Page not found

" +exception: null } }

I also tried calling the controllers directly, but a lot of values that are filled by normal requests are empty in the BackendController.

What do I need to change, set up to be able to test my backend controllers?

Ad

Answer

To test your controller if it will run you'll need to set the execution context to backend and run the backend service provider.

Even so you need to set up an admin test user for the in memory database you can use, because otherwise the controller will try to redirect you to the login page.

use BackendAuth;
use PluginTestCase;
use Backend\Models\User;
use Backend\Classes\Controller;
use MyAuthor\MyPlugin\Controllers\MyController;

class BasicBackendControllerTest extends PluginTestCase
{

    public function setUp() 
    {
        parent::setup();

        $user = User::create([
            'email' => '[email protected]',
            'login' => 'tester',
            'password' => 'test',
            'password_confirmation' => 'test',
            'send_invite' => false,
            'is_activated' => true,            
        ]);

        $user->is_superuser = true;
        $user->save();

        $user = BackendAuth::authenticate([
            'login' => 'tester',
            'password' => 'test'
        ], true);
    }

    public function testCreateIndexView()
    {
        // default this will be at front-end. This needs to be set to 
        // back-end so the service provider we will load will load up 
        // the backend settings.
        app()->setExecutionContext('back-end');

        // registering and running the service provider
        $provider = app()->register('\Backend\ServiceProvider');
        $provider->boot();

        // the magic happens here that allows a controller to be run.
        $provider->register();

        // retrieve the controller instance from child class
        $controller = new MyController();

        $result = $controller->run('index');

        $this->assertEquals(200, $result->status());
    }
}
Ad
source: stackoverflow.com
Ad