Mocking function to fake environment

How can we test an application that makes calles to some external system, for example needs to access a website or a web-base API?
We can hit the external system for every test-run, but that will probably slow down our testing, might get us banned from the web site,
but maybe most importantly (for the tester), the test will be unreliable. In addition, it will be impossible to test cases when the
external web site returns some error condition.

Let's try a simple example in which we fetch a web page and count specific strings.

This code fetches the content of British Daily Mail that provides reliable information on the
status of the world. Once the page is fetched we count how many times given specific strings appear and return the numbers as a reference
to a hash containing "string" => count pairs.

We check the relative popularity of Beyonce and Miley Cyrus and as we can see Beyonce is winnint 26 to 3.
If we run this script perl webapi.t the output will indicate that everything is ok:

1..1
ok 1

Unfortunately the actual content of the website changes and thus the numbers will change. That means our test
will soon break eve though thet actual "application" is still working correctly.

We can solve this by either disregarding the actual number in the result and check only if there was a number.
This will make our test more universal, but weaker. Or, we can replace the content of the web site as returned
by the get function of LWP::Simple.

We have other issues as well. For example how can we test the behaviour of our application in the case when
the Daily Maily web site is down or returns garbage? We could build our fake version of Daily Maily, but it
is probably more simple to fake the get function.

That's what we are going to do. We are going to use Test::Mock::Simple
to fake (or mock) the get function.

Mocking the get function

We load the module using use Test::Mock::Simple; and then
instead of use MyWebAPI we load our module to be tested using
my $mock = Test::Mock::Simple->new(module => 'MyWebAPI');

then we replace the get function imported from LWP::Simple, but an anonymous function we provide,
which will return a simple string:

$mock->add(get => sub {
return 'Beyonce Beyonce Miley Cyrus';
});

We also adjusted the values in the expected hash to reflect the string we return. This is the new version of
the test script:

As it can be seen from the result, the MyWebAPI module does not handle such cases. Is this a bug, or is this the correct behavior?
That's beyond the scope of this article, but now at least we know how to check what happens in this extreme case.