Skip to content

Adding description of how to test a command which expects user input #2398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 26, 2013
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion components/console/helpers/dialoghelper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,49 @@ You can set the max number of times to ask in the ``$attempts`` argument.
If you reach this max number it will use the default value, which is given
in the last argument. Using ``false`` means the amount of attempts is infinite.
The user will be asked as long as he provides an invalid answer and will only
be able to proceed if her input is valid.
be able to proceed if her input is valid.

Testing a command which expects input
-------------------------------------

If you want to write a unit test for a command which expects some kind of input
from the command line, you need to overwrite the HelperSet used by the command::

use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Helper\HelperSet;

// ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneeded empty line here

public function testExecute()
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneeded empty line

// ..
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use 3 dots


$commandTester = new CommandTester($command);

$dialog = new DialogHelper();
$dialog->setInputStream($this->getInputStream('Test\n'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to overwrite the whole helperSet as all you need is calling a setter on the dialog helper:

$dialog = $command->getHelper('dialog');
$dialog->setInputStream(...)

// Equals to a user inputing "Test" and hitting ENTER
// If you need to enter a confirmation, "yes\n" will work

$command->setHelperSet(new HelperSet(array($dialog)));

$commandTester->execute(array('command' => $command->getName()));

// assert

}

protected function getInputStream($input)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asserting is not something that's usually done in a Command test. Mock objects are a better practise

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied this from the description on how to test commands. I think as a comment it is ok because it ilustrates that the command is now being executed and one can either test the outcome or end the test.

{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneeded empty line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure which line you refer to! I guess between methods there should be an empty line, bracets should also be on their own line. I don't see any other empty lines?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) there was an empty line somewhere here, but I commented on the oldest commit, but it is showing the comments on the new commit. Just a github bug..

$stream = fopen('php://memory', 'r+', false);
fputs($stream, $input);
rewind($stream);

return $stream;
}

By setting the inputStream of the `DialogHelper`, you do the same the
console would do internally with all user input through the cli. This way
you can test any user interaction (even complex ones) by passing an appropriate
input stream.