In my Mojolicious app I need to use the client's IP address ($c->tx->remote_address
) for rate limiting of a service. This works well.
I am now trying to build a unit test for this feature, but I am having trouble faking the client's IP in my tests.
First I thought that local_address
in Mojo::UserAgent might do what I want, but that's where the user agent binds the application locally, and changing it breaks everything because it cannot find the app any more.
I then tried using Sub::Override to replace the remote_address
in Mojo::Transaction, but that already applies to the client when I do $t->post_ok
, it tries sending a request to the IP that doesn't exist because the remote address on the client side is the server's address, and I am stuck with a waiting blocking request that will never succeed because the server it wants does not exist.
You can use the following MCVE to try around. The expected result is for the tests to pass.
use strict;
use warnings;
use Test::More;
use Test::Mojo;
use Mojolicious::Lite;
get '/foo' => sub { my $c = shift; $c->render( text => $c->tx->remote_address ) };
my $t = Test::Mojo->new;
$t->get_ok('/foo')->content_like(qr/\Q127.0.0.1/);
# TODO change client IP address to 10.1.1.1
# in a way that the /foo route sees it
$t->get_ok('/foo')->content_like(qr/\Q10.1.1.1/);
done_testing;
I know how to do this with Catalyst and Dancer (or other Test::Plack based systems), but those approaches don't work here.