false negative in unit testing whether plugin is loaded (?)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

false negative in unit testing whether plugin is loaded (?)

David Mintz-3
I got the idea that I should create an ACL front controller plugin that loads only if there is an authenticated user. My reasoning is, if they ain't logged in, why load my ACL class? Send them to the login page, end of story.

Hence, in my Bootstrap,

    function _initFrontControllerPlugins() {
        $log = $this->getResource('log');
        $front = Zend_Controller_Front::getInstance();
        $front->registerPlugin(new Plugin_Authentication());
        if (Zend_Auth::getInstance()->hasIdentity()) {
            $front->registerPlugin(new Plugin_Acl());
            $log->info("yes auth identity, Acl plugin loaded at Bootstrap ".__LINE__ ."\n");
        } else {
            $log->info("no auth identity, ergo acl not loaded at Bootstrap ".__LINE__ ."\n");
        }
    }

In a browser, I can log in, then load another page and see my Firebug logger telling me the ACL plugin class has loaded as it should.

But in my unit test, this assertion fails:

function testAclPluginLoadsIfUserIsAuthenticated() {
       
        $this->loginDavid(); // tested independently and known to work
        $this->resetRequest()->resetResponse();
        $this->dispatch('/admin/index');
        $auth = Zend_Auth::getInstance();
        if (! $auth->hasIdentity()) {
            throw new Exception("test login for admin failed");
        } else {
            echo " OK there is an identity (Acl Test: ".__LINE__.  ")\n";
        }
        if ($auth->getStorage()->read()->username != 'david') {
            throw new Exception("unexpected username is logged in, can't run test");
            return;
        } else {
            echo " OK David is authenticated\n" ;
        }
        $front = $this->bootstrap->getResource('FrontController');
        $this->assertType('Plugin_Acl',$front->getPlugin('Plugin_Acl'),"Plugin_Acl not loaded when it should be");
    }
}

Any ideas what I am doing wrong? (I am, I confess, still fairly new to automated testing but I am an enthusiastic believer.)

btw, I tried simply loading both plugins unconditionally, and when I rewrite the tests to check that both are loaded, it works. But it seems like the tail is wagging the dog when you refactor (de-optimize?) your app just to force tests to pass.

Gratefully,

           David


--
Demand health care for everyone:
http://mobilizeforhealthcare.org/

--
David Mintz
http://davidmintz.org/


Reply | Threaded
Open this post in threaded view
|

Re: false negative in unit testing whether plugin is loaded (?)

prodigitalson
Well first off you shouldnt really throw exceptions in your test... thats what the assertions are for really for example:

function testAclPluginLoadsIfUserIsAuthenticated() {

        $this->loginDavid(); // tested independently and known to work
        $this->resetRequest()->resetResponse();
        $this->dispatch('/admin/index');
        $auth = Zend_Auth::getInstance();
        $this->assertTrue($auth->hasIdentity());
        $this->assertEquals('david', $auth->getStorage()->read()->username);
        $this->assertType('Plugin_Acl',$front->getPlugin('Plugin_Acl'),"Plugin_Acl
not loaded when it should be");
}

If you do it this way youll get more meaningful output from PHP unit. Which brings us to the key question... Where exactly in the test you provided (or my modified version) is it failing?


David Mintz-3 wrote
I got the idea that I should create an ACL front controller plugin that
loads only if there is an authenticated user. My reasoning is, if they ain't
logged in, why load my ACL class? Send them to the login page, end of story.

Hence, in my Bootstrap,

    function _initFrontControllerPlugins() {
        $log = $this->getResource('log');
        $front = Zend_Controller_Front::getInstance();
        $front->registerPlugin(new Plugin_Authentication());
        if (Zend_Auth::getInstance()->hasIdentity()) {
            $front->registerPlugin(new Plugin_Acl());
            $log->info("yes auth identity, Acl plugin loaded at Bootstrap
".__LINE__ ."\n");
        } else {
            $log->info("no auth identity, ergo acl not loaded at Bootstrap
".__LINE__ ."\n");
        }
    }

In a browser, I can log in, then load another page and see my Firebug logger
telling me the ACL plugin class has loaded as it should.

But in my unit test, this assertion fails:

function testAclPluginLoadsIfUserIsAuthenticated() {

        $this->loginDavid(); // tested independently and known to work
        $this->resetRequest()->resetResponse();
        $this->dispatch('/admin/index');
        $auth = Zend_Auth::getInstance();
        if (! $auth->hasIdentity()) {
            throw new Exception("test login for admin failed");
        } else {
            echo " OK there is an identity (Acl Test: ".__LINE__.  ")\n";
        }
        if ($auth->getStorage()->read()->username != 'david') {
            throw new Exception("unexpected username is logged in, can't run
test");
            return;
        } else {
            echo " OK David is authenticated\n" ;
        }
        $front = $this->bootstrap->getResource('FrontController');

$this->assertType('Plugin_Acl',$front->getPlugin('Plugin_Acl'),"Plugin_Acl
not loaded when it should be");
    }
}

Any ideas what I am doing wrong? (I am, I confess, still fairly new to
automated testing but I am an enthusiastic believer.)

btw, I tried simply loading both plugins unconditionally, and when I rewrite
the tests to check that both are loaded, it works. But it seems like the
tail is wagging the dog when you refactor (de-optimize?) your app just to
force tests to pass.

Gratefully,

           David


--
Demand health care for everyone:
http://mobilizeforhealthcare.org/

--
David Mintz
http://davidmintz.org/
Reply | Threaded
Open this post in threaded view
|

Re: false negative in unit testing whether plugin is loaded (?)

David Mintz


On Mon, Oct 26, 2009 at 5:06 PM, prodigitalson <[hidden email]> wrote:

Well first off you shouldnt really throw exceptions in your test... thats
what the assertions are for really for example:

function testAclPluginLoadsIfUserIsAuthenticated() {

       $this->loginDavid(); // tested independently and known to work
       $this->resetRequest()->resetResponse();
       $this->dispatch('/admin/index');
       $auth = Zend_Auth::getInstance();
       $this->assertTrue($auth->hasIdentity());
       $this->assertEquals('david', $auth->getStorage()->read()->username);
       $this->assertType('Plugin_Acl',$front->getPlugin('Plugin_Acl'),"Plugin_Acl
not loaded when it should be");
}

If you do it this way youll get more meaningful output from PHP unit. Which
brings us to the key question... Where exactly in the test you provided (or
my modified version) is it failing?


Um, it's sort of moot now, because the frustration with the tests got me thinking about my code organization, and I decided to collapse my authentication and ACL into a single plugin. But the preDispatch() does not instantiate my Model_Acl unless there is an authenticated user. It has the efficiency of what I was attempting before, and then some, while not presenting any testing problems (yet).

But I take your point about the exception. Although the method is tested elsewhere and so  I figured if it fails here, abort the test run and fix the problem.But -- still learning.

Many thanks.

--
Demand health care for everyone:
http://mobilizeforhealthcare.org/

--
David Mintz
http://davidmintz.org/