FAQ
can someone point me at a nice example of testing a controller while
stubbing out another one with MockObject, please.

basically, I have 2 controllers, they both redirect under various
circumstances which interact. I want to test one in isolation if I
can.

thanks

--
Daniel McBrearty
email : danielmcbrearty at gmail.com
www.engoi.com : the multi - language vocab trainer
BTW : 0873928131

Search Discussions

  • Daniel McBrearty at Jun 3, 2006 at 7:37 am
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.

    cheers

    D

    On 6/3/06, Daniel McBrearty wrote:
    can someone point me at a nice example of testing a controller while
    stubbing out another one with MockObject, please.

    basically, I have 2 controllers, they both redirect under various
    circumstances which interact. I want to test one in isolation if I
    can.

    thanks

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Matt S Trout at Jun 3, 2006 at 10:51 am

    Daniel McBrearty wrote:
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.
    Engoi->components->{Controller::Public} = $mock;

    maybe
  • Daniel McBrearty at Jun 3, 2006 at 3:22 pm
    that doesn't seem to do it either.

    here's the top of my test file :

    use strict;
    use warnings;
    use Test::WWW::Mechanize::Catalyst 'Engoi';
    use Test::MockObject;
    use Test::More tests => 3;
    use Data::Dumper;

    BEGIN {
    my $mock = Test::MockObject->new;
    #Engoi->components->{'Controller::Public'} = $mock;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    }

    I've tried various combinationsof those lines in the BEGIN block ...

    anyone got any ideas? or some example code that works?


    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.
    Engoi->components->{Controller::Public} = $mock;

    maybe

    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Christopher H. Laco at Jun 3, 2006 at 3:26 pm

    Daniel McBrearty wrote:
    that doesn't seem to do it either.

    here's the top of my test file :

    use strict;
    use warnings;
    use Test::WWW::Mechanize::Catalyst 'Engoi';
    use Test::MockObject;
    use Test::More tests => 3;
    use Data::Dumper;

    BEGIN {
    my $mock = Test::MockObject->new;
    #Engoi->components->{'Controller::Public'} = $mock;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    }

    I've tried various combinationsof those lines in the BEGIN block ...

    anyone got any ideas? or some example code that works?


    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.
    Engoi->components->{Controller::Public} = $mock;

    maybe
    Off the top of my head, with no other thoughts, does running an app usin
    Catalyst::Test run the app in a different process than where the .t test
    file actually runs? If so, then any mocking you do in the .t test file
    won't be seen by the running Catalyst app.


    I could be way off base there.
    -=Chris

    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: signature.asc
    Type: application/pgp-signature
    Size: 189 bytes
    Desc: OpenPGP digital signature
    Url : http://lists.rawmode.org/pipermail/catalyst/attachments/20060603/c544e13b/attachment.pgp
  • Matt S Trout at Jun 3, 2006 at 3:37 pm

    Christopher H. Laco wrote:
    Daniel McBrearty wrote:
    that doesn't seem to do it either.

    here's the top of my test file :

    use strict;
    use warnings;
    use Test::WWW::Mechanize::Catalyst 'Engoi';
    use Test::MockObject;
    use Test::More tests => 3;
    use Data::Dumper;

    BEGIN {
    my $mock = Test::MockObject->new;
    #Engoi->components->{'Controller::Public'} = $mock;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    }

    I've tried various combinationsof those lines in the BEGIN block ...

    anyone got any ideas? or some example code that works?


    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.
    Engoi->components->{Controller::Public} = $mock;

    maybe
    Off the top of my head, with no other thoughts, does running an app usin
    Catalyst::Test run the app in a different process than where the .t test
    file actually runs? If so, then any mocking you do in the .t test file
    won't be seen by the running Catalyst app.
    Not by default, no.

    The problem is that Daniel needs to do the ->components->{...} = *after*
    he's loaded Catalyst::Test for Engoi, since until that point the
    appclass components hash isn't there to be modified.
  • Daniel McBrearty at Jun 3, 2006 at 3:38 pm
    something fishy in that BEGIN block, I get this when I do make test:

    [Sat Jun 3 17:29:07 2006] [catalyst] [info] engoi powered by Catalyst 5.67
    t/01app................ok 1/3Called UNIVERSAL::can() as a function,
    not a method at /usr/local/lib/perl/5.8.7/Template/Provider.pm line
    275
    Called UNIVERSAL::can() as a function, not a method at
    /usr/local/lib/perl/5.8.7/Template/Provider.pm line 275
    Called UNIVERSAL::can() as a function, not a method at
    /usr/local/lib/perl/5.8.7/Template/Iterator.pm line 78

    (and loads more like that ... )

    On 6/3/06, Christopher H. Laco wrote:
    Daniel McBrearty wrote:
    that doesn't seem to do it either.

    here's the top of my test file :

    use strict;
    use warnings;
    use Test::WWW::Mechanize::Catalyst 'Engoi';
    use Test::MockObject;
    use Test::More tests => 3;
    use Data::Dumper;

    BEGIN {
    my $mock = Test::MockObject->new;
    #Engoi->components->{'Controller::Public'} = $mock;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    }

    I've tried various combinationsof those lines in the BEGIN block ...

    anyone got any ideas? or some example code that works?


    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.
    Engoi->components->{Controller::Public} = $mock;

    maybe
    Off the top of my head, with no other thoughts, does running an app usin
    Catalyst::Test run the app in a different process than where the .t test
    file actually runs? If so, then any mocking you do in the .t test file
    won't be seen by the running Catalyst app.


    I could be way off base there.
    -=Chris



    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst



    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Daniel McBrearty at Jun 3, 2006 at 3:46 pm
    now I have this :

    BEGIN {
    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    Engoi->components->{'Controller::Public'} = $mock;
    }

    but I still have my errors as before, and the mock object is not being
    used by Cat.

    On 6/3/06, Daniel McBrearty wrote:
    something fishy in that BEGIN block, I get this when I do make test:

    [Sat Jun 3 17:29:07 2006] [catalyst] [info] engoi powered by Catalyst 5.67
    t/01app................ok 1/3Called UNIVERSAL::can() as a function,
    not a method at /usr/local/lib/perl/5.8.7/Template/Provider.pm line
    275
    Called UNIVERSAL::can() as a function, not a method at
    /usr/local/lib/perl/5.8.7/Template/Provider.pm line 275
    Called UNIVERSAL::can() as a function, not a method at
    /usr/local/lib/perl/5.8.7/Template/Iterator.pm line 78

    (and loads more like that ... )

    On 6/3/06, Christopher H. Laco wrote:
    Daniel McBrearty wrote:
    that doesn't seem to do it either.

    here's the top of my test file :

    use strict;
    use warnings;
    use Test::WWW::Mechanize::Catalyst 'Engoi';
    use Test::MockObject;
    use Test::More tests => 3;
    use Data::Dumper;

    BEGIN {
    my $mock = Test::MockObject->new;
    #Engoi->components->{'Controller::Public'} = $mock;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    }

    I've tried various combinationsof those lines in the BEGIN block ...

    anyone got any ideas? or some example code that works?


    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    I am doing this :

    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');

    almost the first thing in the test file.

    Later I do a get on /public/home, but the method in the real
    controller still gets called.
    Engoi->components->{Controller::Public} = $mock;

    maybe
    Off the top of my head, with no other thoughts, does running an app usin
    Catalyst::Test run the app in a different process than where the .t test
    file actually runs? If so, then any mocking you do in the .t test file
    won't be seen by the running Catalyst app.


    I could be way off base there.
    -=Chris



    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst



    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Matt S Trout at Jun 3, 2006 at 4:19 pm

    Daniel McBrearty wrote:
    now I have this :

    BEGIN {
    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    Engoi->components->{'Controller::Public'} = $mock;
    }

    but I still have my errors as before, and the mock object is not being
    used by Cat.
    balls.

    Engoi->components->{'Engoi::Controller::Public'} = $mock;
  • Daniel McBrearty at Jun 3, 2006 at 4:25 pm
    that was it, Matt.

    Thanks!

    All we need now is Sri Lanka 50-5 at close, and I'm off for a drink.
    (but perhaps I ought not to put that condition on it ...)

    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    now I have this :

    BEGIN {
    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    Engoi->components->{'Controller::Public'} = $mock;
    }

    but I still have my errors as before, and the mock object is not being
    used by Cat.
    balls.

    Engoi->components->{'Engoi::Controller::Public'} = $mock;

    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Daniel McBrearty at Jun 3, 2006 at 4:29 pm
    I also get this in the output :

    Engoi::Controller::Public->_DISPATCH "Can't use an undefined value as
    an ARRAY reference at /usr/local/share/perl/5.8.7/Catalyst/Base.pm
    line 19."

    which is this in Base.pm :

    sub _DISPATCH : Private {
    my ( $self, $c ) = @_;
    foreach my $disp ( @{ $self->_dispatch_steps } ) { # line 19
    last unless $c->forward($disp);
    }
    $c->forward('_END');
    }


    ... but i'm not going to worry about it right now ...

    On 6/3/06, Daniel McBrearty wrote:
    that was it, Matt.

    Thanks!

    All we need now is Sri Lanka 50-5 at close, and I'm off for a drink.
    (but perhaps I ought not to put that condition on it ...)

    On 6/3/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    now I have this :

    BEGIN {
    my $mock = Test::MockObject->new;
    $mock->fake_module('Engoi::Controller::Public');
    $mock->set_true('home');
    use_ok('Catalyst::Test', 'Engoi');
    Engoi->components->{'Controller::Public'} = $mock;
    }

    but I still have my errors as before, and the mock object is not being
    used by Cat.
    balls.

    Engoi->components->{'Engoi::Controller::Public'} = $mock;

    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Matt S Trout at Jun 3, 2006 at 4:36 pm

    Daniel McBrearty wrote:
    I also get this in the output :

    Engoi::Controller::Public->_DISPATCH "Can't use an undefined value as
    an ARRAY reference at /usr/local/share/perl/5.8.7/Catalyst/Base.pm
    line 19."

    which is this in Base.pm :

    sub _DISPATCH : Private {
    my ( $self, $c ) = @_;
    foreach my $disp ( @{ $self->_dispatch_steps } ) { # line 19
    last unless $c->forward($disp);
    }
    $c->forward('_END');
    }


    ... but i'm not going to worry about it right now ...
    You can't dispatch to a controller you're mocking unless you mock the
    internal dispatch stuff as well ...
  • Daniel McBrearty at Jun 4, 2006 at 8:59 am

    You can't dispatch to a controller you're mocking unless you mock the
    internal dispatch stuff as well ...
    (testcode)

    BEGIN { use_ok('Catalyst::Test', 'Engoi'); }
    my $mock = Test::MockObject->new;
    $mock->set_true('home');
    Engoi->components->{'Engoi::Controller::Public'} = $mock;

    clearSession();
    my $mech = Test::WWW::Mechanize::Catalyst->new;
    $mech->requests_redirectable( [] );

    $r = $mech->get($dr.'public/home');
    $l = $r->header('location');
    ok( !$r->is_redirect, 'no redirect to natlang with no session');

    (/testcode)

    and this works apart form the error ...

    Obviously I don't want to be having to simulate all the internals of a
    Controller to test ... so I try to use Test::MockObject::Extends
    instead (I only want to override one method, right ...?):

    (newtestcode)
    BEGIN { use_ok('Catalyst::Test', 'Engoi'); }

    my $mock = Test::MockObject::Extends->new(Engoi->components->{'Engoi::Controller::Public'}
    );
    $mock->set_true('home');
    (/newtestcode)

    but now the MockObject stops working ...

    maybe cat loads actions when the script starts, whatever
    MockObject::Extends does is just ignored I guess?

    what am I doing wrong ... seems I am making hard work of something
    that shouldn't be *that* tough ... is there an easier way to do all
    this?

    All I *really* need to do is stub out a method in a controller that I
    am not testing here, stop it redirecting itself and breaking my tests.

    D

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Matt S Trout at Jun 4, 2006 at 11:50 am

    Daniel McBrearty wrote:
    You can't dispatch to a controller you're mocking unless you mock the
    internal dispatch stuff as well ...
    (testcode)

    BEGIN { use_ok('Catalyst::Test', 'Engoi'); }
    my $mock = Test::MockObject->new;
    $mock->set_true('home');
    Engoi->components->{'Engoi::Controller::Public'} = $mock;

    clearSession();
    my $mech = Test::WWW::Mechanize::Catalyst->new;
    $mech->requests_redirectable( [] );

    $r = $mech->get($dr.'public/home');
    $l = $r->header('location');
    ok( !$r->is_redirect, 'no redirect to natlang with no session');

    (/testcode)

    and this works apart form the error ...

    Obviously I don't want to be having to simulate all the internals of a
    Controller to test ... so I try to use Test::MockObject::Extends
    instead (I only want to override one method, right ...?):

    (newtestcode)
    BEGIN { use_ok('Catalyst::Test', 'Engoi'); }

    my $mock = Test::MockObject::Extends->new(Engoi->components->{'Engoi::Controller::Public'}
    );
    $mock->set_true('home');
    (/newtestcode)

    but now the MockObject stops working ...

    maybe cat loads actions when the script starts, whatever
    MockObject::Extends does is just ignored I guess?

    what am I doing wrong ... seems I am making hard work of something
    that shouldn't be *that* tough ... is there an easier way to do all
    this?

    All I *really* need to do is stub out a method in a controller that I
    am not testing here, stop it redirecting itself and breaking my tests.
    If you're not testing Controller::Public, why are you dispatching a
    request to "public/home" in the first place?
  • Daniel McBrearty at Jun 4, 2006 at 12:04 pm
    good question ... I have an auto action in the root controller which
    redirects unless the request is to public/home OR (some other stuff).

    Maybe I should move that action into Root.

    On 6/4/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    You can't dispatch to a controller you're mocking unless you mock the
    internal dispatch stuff as well ...
    (testcode)

    BEGIN { use_ok('Catalyst::Test', 'Engoi'); }
    my $mock = Test::MockObject->new;
    $mock->set_true('home');
    Engoi->components->{'Engoi::Controller::Public'} = $mock;

    clearSession();
    my $mech = Test::WWW::Mechanize::Catalyst->new;
    $mech->requests_redirectable( [] );

    $r = $mech->get($dr.'public/home');
    $l = $r->header('location');
    ok( !$r->is_redirect, 'no redirect to natlang with no session');

    (/testcode)

    and this works apart form the error ...

    Obviously I don't want to be having to simulate all the internals of a
    Controller to test ... so I try to use Test::MockObject::Extends
    instead (I only want to override one method, right ...?):

    (newtestcode)
    BEGIN { use_ok('Catalyst::Test', 'Engoi'); }

    my $mock = Test::MockObject::Extends->new(Engoi->components->{'Engoi::Controller::Public'}
    );
    $mock->set_true('home');
    (/newtestcode)

    but now the MockObject stops working ...

    maybe cat loads actions when the script starts, whatever
    MockObject::Extends does is just ignored I guess?

    what am I doing wrong ... seems I am making hard work of something
    that shouldn't be *that* tough ... is there an easier way to do all
    this?

    All I *really* need to do is stub out a method in a controller that I
    am not testing here, stop it redirecting itself and breaking my tests.
    If you're not testing Controller::Public, why are you dispatching a
    request to "public/home" in the first place?

    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131
  • Matt S Trout at Jun 4, 2006 at 12:17 pm

    Daniel McBrearty wrote:
    good question ... I have an auto action in the root controller which
    redirects unless the request is to public/home OR (some other stuff).

    Maybe I should move that action into Root.
    Or test that by mocking the $c ...
  • Daniel McBrearty at Jun 5, 2006 at 9:54 am
    in this case it probably makes sense to move it, as the functions are
    quite tightly bound.

    how do I get access to the $c in the test though? via $mech? I
    huyaven't been able to figure this as yet.

    On 6/4/06, Matt S Trout wrote:
    Daniel McBrearty wrote:
    good question ... I have an auto action in the root controller which
    redirects unless the request is to public/home OR (some other stuff).

    Maybe I should move that action into Root.
    Or test that by mocking the $c ...

    _______________________________________________
    Catalyst mailing list
    Catalyst at lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst

    --
    Daniel McBrearty
    email : danielmcbrearty at gmail.com
    www.engoi.com : the multi - language vocab trainer
    BTW : 0873928131

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedJun 3, '06 at 7:12a
activeJun 5, '06 at 9:54a
posts17
users3
websitecatalystframework.org
irc#catalyst

People

Translate

site design / logo © 2021 Grokbase