1

I'm creating a library and I want to test a system that asks the user by input in the console. I use PHPUnit as a testing library but and I don't know how to execute readline function and then print a text to answer the input to test it.

Here it is my test:

$app = new Application;
$i = null;
$app->registerCommand('test', function(Input $input) use(&$i){
    // $input->getInput() asks the user and returns the value
    $i = $input->getInput();
});

$this->expectOutputString("\n");
// Run the application, so asks the user to enter a value
$app->run();
// Here, I want force to enter a value by the code
$this->assertSame($i, 'test');

I've tested to replace readline by fgets(STDIN) but without results. I thought to solve the problem with asynchronous callables but I need guide for good libraries to use.

Here it is differents ways I've tested in getInput function:

return readline();
return trim(fgets(STDIN));

Thank for your help.

YaFou
  • 51
  • 6
  • For whatever **Application** is (you have not shared in your question), does it have any method that you can provide input? Otherwise you would always need to enter something manually when running the test which defeats automated testing... . – hakre Nov 19 '19 at 20:56

1 Answers1

0

Try replacing the use of read line or some 3rd party prompt command with your own function and use the following:

You can read keyboard input manually in php with this:

$fp = fopen("php://stdin", "r");
$input = rtrim(fgets($fp, 1024));

Note the string with std input used as the input stream. And then when testing replace the input stream with a file like so

$fp = fopen(__DIR__ . '/../test/test_input', "r");
$input = rtrim(fgets($fp, 1024));

This time it will read a single line from the file instead.

Obviously you will have to make a function and some way to swap the input stream string during testing but the above is all you need to get it working.

Here is a working unit test:

class PromptTest extends TestCase
{

    public function testPrompt()
    {
        $fp = fopen(__DIR__ . '/../test/test_input', "r");
        $rtrim = rtrim(fgets($fp, 1024));
        self::assertEquals('first line of file', $rtrim);
    }
}

This produced OK (1 test, 1 assertion)

ALso found here: Is there a way to access a string as a filehandle in php? that a string input can be used.

Brad
  • 741
  • 7
  • 17