Unit Testing in PHPUnit - Handling Multiple Conditions - php

I want to write a test using PHPUnit which includes a check to make sure that a value is either a string or NULL.
AFAIK, I can write such a test like so:
if (is_string($value) || is_null($value)) {
$result = TRUE;
} else {
$result = FALSE;
}
$this->assertTrue($result);
However, I've seen that PHPUnit has a logicalOr() method, which I don't know if I should be using to make a more 'native' test? And if I should be using it, I can't figure out how to do so...

Using phpunit v5.5 it (also) works this way:
if (is_string($value) || is_null($value)) {
$result = TRUE;
} else {
$result = FALSE;
}
$this->assertThat($value, $this->logicalOr(
$this->isType('string'),
$this->isNull()
));

logicalOr returns an object that is used to build a condition that can be passed to assertThat. I can't check the syntax on my phone, but it should look something like this:
self::assertThat(self::logicalOr(self::stringValue(), self::nullValue()));
The method names are no doubt incorrect as I am used to Hamcrest, but I he structure is similar.

The best approach is the one which will give you the most usable output in the event of a problem. In this case, I don't think it matters too much which way you so it, as long as you know what went wrong. The following code will provide a meaningful error message:
$message = '$value should have been either a string or null, but was actually a '
.gettype($value);
$this->asertTrue($valueIsEitherStringOrNull, $message);

Related

Mockery: check argument is passed at least once?

I'm looking to do something that seems rather usual but can't find a built-in solution in Mockery.
An example test would be something like this:
<?php
$user = factory(App\User::class)->create(['birthday' => Carbon::now()->subYear(20)]);
$this->mailer->shouldReceive('sendBirthdayEvent')
->with(hasEntry("id", $user->id)); // Will fail if DB is seeded
$this->command->sendBirthdayEventToAllUSers();
I'd like to check that the sendBirthdayEvent will be call for the used I just created once.
Problem is I can't use with because my database might be seeded at that point and other users could also have birthdays on the same day.
The 'smarter' solution I've thought of until now is to do something like this:
<?php
$success = false;
$this->mailer->shouldReceive('sendBirthdayEvent')
->with(function($user_id) use($success) {
if($user_id) === $user->id {
$success = true:
}
return true;
});
assert($success,true);
But I feel like I'm really missing something here.
Try this:
$this->mailer->shouldReceive('sendBirthdayEvent')->with($user->id)->once();

php - turn-on/off-able function to print debugging messages

I am quite new to programming, when I develop my program I use a simple strategy to debug it: I write the program to print along the debugging messages as it operate the significant statements, for example
function foo1($number)
{
//foo_print("I am function foo1({$number}). <br/>");
//foo_print("I am going to increase 'count' by {$number}. <br/>");
$GLOBALS["count"] = $GLOBALS["count'] + $number;
//foo_print("Now 'count' = {$GLOBALS["count"]}, I finished my task, BYE BYE. <br/>");
}
function isFoo($number)
{
//foo_print("I am function isFoo({$number}). <br/>");
//foo_print("I am checking if the number < 3 or not, if so, it is Foo, if not, it is not Foo. <br/>");
if($number <= 3)
{
//foo_print("Found that number = {$number} <= 3, I return true, BYE BYE. <br/>");
return true;
}
//foo_print("Found that number = {$number} > 3, I return false, BYE BYE. <br/>");
return false;
}
I call them debugging messages but, as you see, they're actually the thoroughly comments describing what does the program do on each line. I just write the function foo_print() to print them out when I am debugging the program. And comment them out in real use.
Instead of inserting and removing the comment sign '//' line by line in and out when switch between real run mode and debugging mode, I have the function foo_print to do the work: It can be set to turn on or off.
define(FOO_PRINT, 1)
function foo_print($message)
{
if(FOO_PRINT) print $message;
// if FOO_PRINT == 0 then do nothing.
}
But I think this method is ineffective, it has to check FOO_PRINT every time before printing a message.
My question is either or both of the following
Can I do something to tell php to ignore my foo_print() function when I don't want to use it?
Perhaps, instead of using foo_print function, I should write the messages in plain comment style using '//' sign and then tell php interpreter to print those comment messages when in debugging mode. Can I do that?
I think, other than debugging ease, this method will be of advantage that it can help me understand the program when I come back to see it in later days. (It very long and complicated for me that I believe I will forget it soon.)
I found it very complicated for me now to use advanced IDEs and debugging tools to develop my program. I believe some of these advanced debugging tools can do something similar to what I want, but I've tried on PHP-eclipse and xdebug for a week and it got me nowhere. thank you very much.
You could define two functions, one of which outputs the debug data and the other one doesn't. Then use a variable name to contain the name of the function you want to call and do your debugging by calling the function in the variable. Like this:
function debug_print($data) {
echo $data;
}
function debug_none($data) {
}
$debug = 'debug_print';
$debug('Testing one'); // This prints out 'Testing one'
$debug = 'debug_none';
$debug('Testing two'); // This doesn't print out anything
If you do this, don't forget to add global $debug to any functions that want to use the function.
EDIT: There is also a more object oriented way to achieve the same result. You could define an interface and write a couple of implementations for it, allowing you to choose which one to use at runtime.
$debugmode = true;
interface Debugger {
public function out($data);
}
class EchoDebugger implements Debugger {
public function out($data) {
echo $data;
}
}
class NullDebugger implements Debugger {
public function out($data) {
// Do nothing
}
}
if($debugmode)
$debugger = new EchoDebugger();
else
$debugger = new NullDebugger();
$debugger->out('This will be output if $debugmode is true');
No bud,
there is no such thing possible, and you have to define a condition every time.
This cannot be done in code of php

Is it possible to get the statements within a method in PHP?

function mainFunction() {
functionA(5, "blah");
functionB("ok", "whatever");
}
How to write a function GetFunctions that returns the functions within mainFunction?
How to call them with the parameters given in mainFunction?
How to call them as follows?
foreach (GetFunctions(mainFunction) as $function) {
print "Calling function $function: ";
call($functionA); // called with parameters(5, "blah")
}
Working in PHP 5.2.8
EDIT: OK, here's a more complete explanation. I tried to keep it simple to make it easy to understand, but apparently that wasn't a good idea.
The goal is to call each assertion within a given static method. I am writing a testing framework. Each assertion returns true or false.
I am calling the methods as follows.
$methods = get_class_methods('LibraryTests');
foreach ($methods as $method) {
if ( StartsWith($method, 'Test') ) {
print "calling: " . $method . ": ";
call_user_func('LibraryTests::' . $method);
}
}
The above code calls each method within the class, but I want to call each assertion individually and track the result (true/false). CallAssertion is supposed to call each assertion (such as TestUnit::AssertEqual(GetFormattedHour(5), "5 PM");). This is the method that I am asking about.
Here is the class:
class LibraryTests extends TestUnit {
static $success = 0;
static $failure = 0;
static $total = 0;
static function CallAssertion($assertion) {
self::$total += 1;
if ($assertion) { self::$success += 1; }
else { self::$failure += 1; }
}
static function TestGetFormattedHour() {
TestUnit::AssertEqual(GetFormattedHour(5), "5 PM");
TestUnit::AssertEqual(GetFormattedHour(16), "4 PM");
}
So, the question is, how to write CallAssertion?
You can't.
Instead, create a class and use reflection to get its methods.
Regardless, you'll want to figure out why this is necessary and see if there is an entirely different approach you can use.
(If this is for debugging purposes, you can use debug_backtrace to inspect but its purpose is not for calling functions as you have described in your question.)
Hmm, what problem are you actually trying to solve. To me it sounds like you're trying to inspect the call stack at runtime. If so, I'd suggest just using debug_backtrace() (src).
I wouldn't suggest using that function in production as much though, as it's a rather heavy hit on your code.
One possibility would be to do a file_get_contents on the PHP file that contains main_function, then go through it to parse out main_function and the functions it calls. Of course, I don't know your situation so that might not work.
You can do this with:
http://php.net/manual/en/function.token-get-all.php
Probably a bad idea, but good luck!

php activerecord save does not work in codeigniter

I use the latest code igniter (2.0.3) and php-active 0.0.1.
All are working fine except save();
Code:
if($_POST)
{
$entry= Customers::find_by_routeid('4');
$entry->routeid=5;
$entry->save();
}
Here's my problem: for some reason that I cannot understand the above code does not work, but if I take the code out of if ($_POST), it works fine.
What I am doing wrong?
EDIT:
Thanks Damien Pirsy $this->input->post() does the trick, but when I uncomment the comments in the code the problems returns.
The code now is:
if($this->input->post())
{
$id = $this->input->post('id');
$oldRoute = $this->input->post('oldRoute');
$newRoute = $this->input->post('newRoute');
$entry= Customers::find_by_routeid($this->input->post('oldRoute'));
$entry->routeid=$this->input->post('newRoute');
$entry->save();
/*
if($oldRoute<$newRoute)
{
for ($i=$newRoute; $i>$oldRoute; $i--)
{
$element = Customers::find_by_routeid($i);
echo $element->routeid -= 1;
$element->save();
}
}
*/
}
The elements new IDs ($element->routeid -= 1;) are echoing right, but I have the same problem as in the beginning and neither of two saves work.
You didn't provide much details or debug info, so I'll just guess: try using the CI's native post handler instead. You should have var_dump()ed the $_POST array, see if isset() or not, also, since you're using it as a condition
if($this->input->post())
{
//...
}
UPDATE:
Since we're talking about Post variables, don't assume they're exactly as you want them. Keep in mind that $this->input->post('field') returns FALSE when the index is not present; that might well brake your if condition.
Assuming you need numbers to do this, you can do a check like
if($this->input->post('newRoute') AND is_numeric($this->input->post('newRoute'))
{
$newRoute = $this->input->post('newRoute');
}
else
{
// give it a default value, or raise an error, for example. If you need this
// variables, and need them to be numbers, you cannot go on in case these
// conditions are not met, right?
}
And the same for $oldRoute.
And yeah, OK, maybe you can write a cleaner code than mine, but you get the picture ;)

How would you go about validating that a regex actually compiles and works, ie doesn't throw an error?

I'm creating an administration panel that has regex's submitted to it. Any ideas on how I would go about validating the submitted regex's to see if they work. When I say "see if they work" I mean if the regex's are valid and compile properly, not that they actually match data or not?
FYI, This would be in PHP.
Solved it myself after checking the docs.
preg_match('/'.$pattern.'/', 'foobar foobar foobar');
if(preg_last_error() === PREG_NO_ERROR)
{
// ok
}
preg_match returns boolean false on error so it's a simple matter of checking the return value (make sure you use the === not ==) and suppress the warning output:
if (#preg_match('/some expression/', '') === false) {
// bad regex
}
Another solution that wont throw a warning but uses ugly error supressing...
$good_re = '~\d+~';
$bad_re = '##$';
$good_check = #preg_match( $good_re, 'asdd' );
var_dump($good_check);
$bad_check = #preg_match( $bad_re, 'asdd' );
var_dump($bad_check);

Categories