PerlDancer / Dancer2

Perl Dancer Next Generation (rewrite of Perl Dancer)
http://perldancer.org/
Other
542 stars 274 forks source link

How to stub a service in Dancer? #1640

Open janlimpens opened 2 years ago

janlimpens commented 2 years ago

I would want to stub services my actions use. I asked at stackoverfow, so I hope you don't mind me posting this here, too:

https://stackoverflow.com/questions/71225977/stubbing-mocking-a-service-in-a-dancer2-application

Usually, I have a setup similar to this:

#!/usr/bin/env perl
package Demo;
use Dancer2;
use Moose;

sub get($self, $params) {
    my $whatever = ...; # connect with db and do stuff
    return $whatever;
}

my $service = Demo->new();

sub make_web_friendly($param) { # no $self, here!
    return "Hello $param!";
}

get '/' => sub {
    my $response = $service->get(query_parameters);
    return make_web_friendly($response);
};

start;

This way, I can separate concerns pretty well and my services are testable without going over a bogus web request via Plack::Test;

However, whenever I test the request, I always also test the service, with goes against this separation.

I would want to provide the Plack Test with a stubbed service that would mock a service answer. So (I assume) either I can make the get action somehow $self-aware, or would have to pass the mocked service to Plack.

# this is put together to showcase the principle, it does not work

package Stub {
    use Moose;
    use Test::More;
    use Data::Dumper;

    sub get($self, $params) {
        diag "I received:" . Dumper($params);
        return "Bianca!";
    }
}

my $app = Demo->to_app;
my $test = Plack::Test->create($app);
my $stub = Stub->new();
$test->service($stub);
my $request  = HTTP::Request->new( GET => '/' );
my $response = $test->request($request);
is $response, 'Hello, Bianca', 'Bianca was here';

How can I achieve (something like) this?