On 16 August 2017 at 21:02, Ryan Jentzsch <ryan.jentz...@gmail.com> wrote:
>
> Is there an RFC that I didn't find that allows for easily overriding
>built-in functions?

No, but there is an extension: https://pecl.php.net/package/uopz

However, I believe the maintainer of it recommends avoiding using it
if at all possible because:

> However in the constructor of this class is the following line to
> get the expected JSON string:
>
> $result = file_get_contents('php://input');
>
> I can not override the file_get_contents() function. The work around is to
> monkey patch the class as a mock and override the constructor

Your workaround is bad solution to the wrong problem.

Trying to unit test things that interact with the real world is
fundamentally broken thing to try to do.

A much better thing to do would be to isolate the internal layers of
your application from the 'horrible outside world', by extracting the
bit that interacts with the outside world with an interface to be
injected:

interface InputReader {
    public function getString();
}

class PhpInputReader implements InputReader {
    public function getString() {
         return file_get_contents('php://input');
    }
}

And then inject a mock version of InputReader when you are doing a
unit test for the class that now depends on an InputReader.

And just to be clear; it is fundamentally impossible to write a unit
test for the class PhpInputReader, as it interacts with the system and
so can't be unit tested. Trying to force a unit-test for something
that should have an integration test is just the wrong thing to do.

There's a talk by a guy called J B Rainsberger that helped me
understand the exact nature of unit tests and integrated tests:
https://www.youtube.com/watch?v=VDfX44fZoMc or
http://vimeo.com/80533536

I really strongly recommend watching it to anyone who is thinking that
replacing functions like file_get_contents() with test version is an
appropriate thing to do.

cheers
Dan
Ack

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to