patternphpMinor
BDD tests in PHPUnit
Viewed 0 times
bddphpunittests
Problem
No one in my team knows how to write BDD tests, so I started writing some and it's quite working well. I think the time has come to improve the code quality.
This contains a lot of duplicated code and unused features:
```
given('For a mValue (mixedValue) and we want to validate if it is an integer')
->when('sJobId is a positive integer', 123)
->then('return of positive integer should be', 'TRUE')
->when('sJobId is a negative integer', -123)
->then('return of a negative integer should be', 'FALSE')
->when('sJobId is a float', 1.23)
->then('return of a float should be', 'FALSE')
->when('sJobId is a string containing only digits', '123')
->then('return of a string (containing only digits) should be', 'TRUE')
->when('sJobId is a string containing not only digits', '123abc-?')
->then('return of a string (containing not only digits) should be', 'TRUE');
}
public function runGiven(&$world, $action, $arguments) {
switch($action) {
case 'For a mValue (mixedValue) and we want to validate if it is an integer': {
$world['helper'] = new cHelperValidation();
}
break;
default: {
return $this->notImplemented($action);
}
}
}
public function runWhen(&$world, $action, $arguments) {
switch($action) {
case 'sJobId is a positive integer': {}
case 'sJobId is a negative integer': {}
case 'sJobId is a float': {}
case 'sJobId is a string containing only digits': {}
case 'sJobId is a string containing not only digits': {}
break;
default: {
return $this->notImplemented($action);
}
}
}
public function runThen(&$world, $action, $arguments) {
switch($action) {
case 'return of positive integer shou
This contains a lot of duplicated code and unused features:
```
given('For a mValue (mixedValue) and we want to validate if it is an integer')
->when('sJobId is a positive integer', 123)
->then('return of positive integer should be', 'TRUE')
->when('sJobId is a negative integer', -123)
->then('return of a negative integer should be', 'FALSE')
->when('sJobId is a float', 1.23)
->then('return of a float should be', 'FALSE')
->when('sJobId is a string containing only digits', '123')
->then('return of a string (containing only digits) should be', 'TRUE')
->when('sJobId is a string containing not only digits', '123abc-?')
->then('return of a string (containing not only digits) should be', 'TRUE');
}
public function runGiven(&$world, $action, $arguments) {
switch($action) {
case 'For a mValue (mixedValue) and we want to validate if it is an integer': {
$world['helper'] = new cHelperValidation();
}
break;
default: {
return $this->notImplemented($action);
}
}
}
public function runWhen(&$world, $action, $arguments) {
switch($action) {
case 'sJobId is a positive integer': {}
case 'sJobId is a negative integer': {}
case 'sJobId is a float': {}
case 'sJobId is a string containing only digits': {}
case 'sJobId is a string containing not only digits': {}
break;
default: {
return $this->notImplemented($action);
}
}
}
public function runThen(&$world, $action, $arguments) {
switch($action) {
case 'return of positive integer shou
Solution
Your switch statements will run through until they find a break statement. Having the braces {} only defines a block of code and has no effect on breaking out of the case.
The one above prints out "OneTwoAlso default" whereas the following prints out "One".
I think your testing would be cleaner if you didn't use
You could do more clever things than this. Also a test will not always be so simple. Normally I find that I have mocked objects and am ensuring that they get called appropriately.
switch (1)
{
case 1: {
echo 'One';
}
case 2: {
echo 'Two';
}
default: {
echo 'Also default';
}
}The one above prints out "OneTwoAlso default" whereas the following prints out "One".
switch (1)
{
case 1:
echo 'One';
break;
case 2:
echo 'Two';
break;
default:
echo 'Also default';
}I think your testing would be cleaner if you didn't use
then and when methods. Normally I create an array of test data and expected results and loop over them. As you are writing the test for the isId method I would have something like this:public function test_isID()
{
$object = new Object_That_You_Are_Testing();
$tests = array(
array('Data' => 123,
'Expected_Result' => true,
'Test_Name' => 'Positive Integer'),
array('Data' => -123,
'Expected_Result' => false,
'Test_Name' => 'Negative Integer'));
foreach ($tests as $test)
{
$this->assertEquals($test['Expected_Result'],
$object->isID($test['Data']),
$test['Test_Name'] . ' Failed');
}
}You could do more clever things than this. Also a test will not always be so simple. Normally I find that I have mocked objects and am ensuring that they get called appropriately.
Code Snippets
switch (1)
{
case 1: {
echo 'One';
}
case 2: {
echo 'Two';
}
default: {
echo 'Also default';
}
}switch (1)
{
case 1:
echo 'One';
break;
case 2:
echo 'Two';
break;
default:
echo 'Also default';
}public function test_isID()
{
$object = new Object_That_You_Are_Testing();
$tests = array(
array('Data' => 123,
'Expected_Result' => true,
'Test_Name' => 'Positive Integer'),
array('Data' => -123,
'Expected_Result' => false,
'Test_Name' => 'Negative Integer'));
foreach ($tests as $test)
{
$this->assertEquals($test['Expected_Result'],
$object->isID($test['Data']),
$test['Test_Name'] . ' Failed');
}
}Context
StackExchange Code Review Q#6606, answer score: 3
Revisions (0)
No revisions yet.