1

I am writing my first phpunit test, here is class for test

require_once "../../configure.php";

class OrderTest extends PHPUnit_Framework_TestCase
{


    public function testLoadOrder_O275()
    {
        $o = new Order(275);
        $this->assertEquals(275, $o->OrderID);
    }

    public function testLoadOrder_O1_Fail(){
        $o2 = new Order(1);
        $this->assertEquals(1, $o2->OrderID);
    }
}

I have two other classes which are autoload using my configure.php, first is DB class that connect to db using mysqli extension and other is Order class that take int as input for construct and load it from database.

My first test succeed to load but second test gives

DB::Execute(): Couldn't fetch mysqli

Where DB is class name and Execute is my public function in that class [not static]. If I reverse the order of functions then first function start giving same error, but later works. Any reason? or solution?

NOTE: When I reconnect to DB in my test it works fine. So, now my question is why it is closing the Database Connection? When I don't have explicit closing in my code.

2
  • Just guessing but, could it be possible that you're storing the mysqli object in a static variable that gets closed after the construction of the object? That'd explain the error in the second test. Commented Jan 2, 2015 at 13:53
  • mysqli object is stored in member variable of my DB class, I never close that object in code except only in destructor of DB class. Which is not the case. But I believe it has something to do with my installation of PHP unit. Commented Jan 2, 2015 at 15:30

1 Answer 1

3

PHPUnit is trying to serialize and deserialize your DB class, which is killing your connection. I've had this same problem.

You are going to need to do one of a few things: (1) use better dependency injection to remove the DB dependencies, (2) mock your DB class for testing purposes, (3) reconnect in each test method that needs DB access, or (4) tell PHPUnit not to serialize and deserialize the class using some combination of $backupGlobalsBlacklist, @backupStaticAttributes, and $backupStaticAttributesBlacklist, depending on your code. (The last two look like the most relevant based on what you have posted.)

You can read more about the problem and the last option above in the documentation.

Sign up to request clarification or add additional context in comments.

3 Comments

I try #3 and it does allow me to work for now, but your post did explain the cause of error. Can you put little more light on #1 and #2, I am not sure if my method is actually best way to write code? Don't we just connect to db once in some wrapper class and reuse. because testing environment didn't like it.
Well, the issue is that you appear to be using a singleton (or at least a static class). That's often fine in production code to prevent needless connects and disconnects, but it's extremely hard to test. Rather than using singletons, you are better off doing dependency injection everywhere. You can find lots of good tutorials by searching for "dependency injection" on any search engine. Unfortunately, refactoring your code to make it more testable is going to be a pain; there's no real way around that.
I use ` @backupGlobals disabled` and it does solve my problem, My Global Variables do not change in code, though I make them variable but they are mainly used as Define constants for me. You are write I cannot change my 8yr old now, but I want to upgrade it in best practise. Ah, self learning is slow and hard at time :). Thanks for your answer though it solve my issue and insight me to new stuffs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.