Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faking error conditions in the mysqli library

Tags:

php

testing

I have a variety of PHP scripts that use the mysqli suite of functions to access a database. I have wrote these scripts to handle the various error conditions (e.g. mysqli_stmt_execute returning false).

Is there a simple way of faking these error conditions to verifty that the output received by the user is approproiate for these conditions?

like image 996
Ed Heal Avatar asked Jul 27 '12 12:07

Ed Heal


2 Answers

If you are using the mysqli classes.

for example:

<?php
     $mysqli = new mysqli("localhost", "user", "password", "db");
     $query = "INSERT INTO some_table (some_field) VALUES ('some_vale')";
     $stmt = $mysqli->prepare($query);
     if (false === $stmt->execute()) {
         echo "Oops! some_value for same_field in some_table returned false";
     }

Mock the classes and overwrite statement execute.

<?php
    class my_mysqli extends mysqli
    {
        public function prepare ($query)
        {
            return new my_mysqli_stmt();
        }

    }

    class my_mysqli_stmt extends mysqli_stmt {
        public function execute ()
        {
            return false;
        }
    }

all you need to change to have every execute method return false is:

<?php
     $mysqli = new my_mysqli("localhost", "user", "password", "db");

If you're using the functions instead

for example:

<?php
     $mysqli = mysqli_connect("localhost", "user", "password", "db");
     $query = "INSERT INTO some_table (some_field) VALUES ('some_vale')";
     $stmt = mysqli_prepare($mysqli, $query);
     if (false === mysqli_stmt_execute($stmt)) {
         echo "Oops! some_value for same_field in some_table returned false";
     }

Monkey patch in namespace php >= 5.3

<?php
    namespace my_faking_namespace {
        function mysqli_stmt_execute($stmt) 
        {
            return false;    
        }

        $mysqli = mysqli_connect("localhost", "user", "password", "db");
        $query = "INSERT INTO some_table (some_field) VALUES ('some_vale')";
        $stmt = mysqli_prepare($mysqli, $query);
        if (false === mysqli_stmt_execute($stmt)) {
            echo "Oops! some_value for same_field in some_table returned false";
        }
    }

Your script will be calling my_faking_namespace\mysqli_stmt_execute() instead of the php version.

note: this wont work if you are calling the functions like \mysqli_stmt_execute() as this version explicitly calls the global namespace.

The not so easy alternatives, for completion purposes

These modify the functions at the call stack level, altering php internally through the use of custom extension modules (requires installation).

  • Advanced PHP debugger has override_function() and rename_function()
  • runkit has runkit_function_copy, runkit_function_redefine, runkit_function_remove, runkit_function_rename and can change just about anything you desire.

nJoy!

like image 128
nickl- Avatar answered Oct 02 '22 08:10

nickl-


If you are looking for automate testing, the best way to go (with PHP) is PHPUnit.

With PHPUnit you can write unit tests (assertions in particular) which allow you to verify that the output received by the user is appropriate in every different condition.

like image 40
bitfox Avatar answered Oct 02 '22 07:10

bitfox