0

I'm working on a PHPUnit test for 3rd party code that does an fgets() command and waits for input, which basically blocks my unit test. Does anyone have a suggestion on how to pass data to fgets() from a unit test?

For example sake, what I'd like to do is something like this:

<?php
$myinput = "GO SOUTH\n";
magicallyQueueIntoSTDINBuffer($myinput);
assertTrue($game->listen() === "You enter the cave"); // Right now, this halts everything.
?>

The above assumes that $game->listen() listens to STDIN, hears "GO SOUTH" and returns "You enter the cave"

The real code is more complicated, but the above puts the essence into context.

Anthony
  • 5,275
  • 11
  • 50
  • 86
  • 3
    This is a good case for a dependency-injected abstraction. Instead of calling `fgets` directly in your code, you pass an object which wraps that function to the `$game` constructor. This object can then be mocked in unit tests. – deceze Jul 15 '14 at 14:22
  • 1
    I agree, but unfortunately I'm using 3rd party code. (PHPAGI for asterisk, to be exact) It has fgets() hard-coded in the library. I could hack it, but then I'd have to reimplement the hack whenever the code changes, or freeze my version of it. Was just seeing if there were other options. – Anthony Jul 15 '14 at 14:38

1 Answers1

1

My suggestion would be to move the call to fgets into its own method (so that it is the only line of code in that method). This way you can test all of your other code normally.

For testing the actual call to fgets, I would recommend looking into PHP's overide_function and rename_function functions. This article is also a good read. Quoting the steps involved from that article:

However, when you go to restore a function, it turns out that does not work. What you actually need to do is:

  1. Use rename_function to give a name to the old, original function, so we can find it later.

  2. Use override_function to define the new behaviour

  3. Use rename_function to give a dummy name to __overridden__

Jeff Lambert
  • 24,395
  • 4
  • 69
  • 96
  • I was actually trying to do this, but have been having trouble getting APD installed. This does seem like the best option - if I could get the darn function installed. – Anthony Jul 15 '14 at 14:43
  • are you using pear or pecl to install it? windows or mac or linux? – Jeff Lambert Jul 15 '14 at 14:44
  • I posted the issue in another post: http://stackoverflow.com/questions/24612979/trouble-installing-pecl-apd-on-ubuntu/24690411?noredirect=1#comment38418493_24690411 Apparently the fix requires doing more patching than I'm comfortable with. I also have to add this code to multiple boxes, so I don't want to make the installation more complicated for each box. – Anthony Jul 15 '14 at 15:49