PHPUnit question concerning mock objects...

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

Post Reply
Forum Newbie
Posts: 2
Joined: Tue Nov 27, 2007 10:42 am

PHPUnit question concerning mock objects...

Post by nbenes »

I've found that the PHPUnit documentation doesn't cover as much as it probably should, and it leaves a few things out entirely, making assumptions that you know what it's talking about.

One such instance is when it's discussing mock objects (I know, PHPUnit's mock object support isn't as good as SimpleTest's, but my company switched from SimpleTest to PHPUnit for some reason, so I need to learn to cope)...I guess my main question is where and how do I get access to the $subject->attach() method that it examples? This is from here: ... jects.html, and the excerpt:

Code: Select all

require_once 'PHPUnit/Framework.php';
class ObserverTest extends PHPUnit_Framework_TestCase
    public function testUpdateIsCalledOnce()
        // Create a Mock Object for the Observer class
        // mocking only the update() method.
        $observer = $this->getMock('Observer', array('update'));
        // Set up the expectation for the update() method
        // to be called only once and with the string 'something'
        // as its parameter.
        // Create a Subject object and attach the mocked
        // Observer object to it.
        $subject = new Subject;
        // Call the doSomething() method on the $subject object
        // which we expect to call the mocked Observer object's
        // update() method with the string 'something'.
Most of this I understand just fine, but where is this

Code: Select all

$subject = new Subject;
coming from? The way I see it, $subject is the object that i'm testing, while $observer is using PHPUnit's mock API to observe the subject. But where does ->attach() come from? It certainly isn't a function that is on my actual object under test, and trying to actually say new Subject says that such an object doesn't exist (so it's not something PHPUnit made up).

Does anyone know how I can attach the two? Or rather, what $subject is, and where the attach() method comes from?

Also, I really hope you guys get that PHPMock framework up and running, it looks awesome and I will definately use it over this weird PHPUnit mock implementation.
User avatar
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Subject is an example class used in documentation (from its name it appears to be a part of an implementation of Observer pattern) as a class under test. Observer is an object that we mock to isolate object under test. Both are supposed to exist and are used for example purposes. It's not something PHPUnit provides. Instead of them you will use your class names, their methods and their behaviour when writing real tests.
Forum Newbie
Posts: 1
Joined: Fri Apr 08, 2011 10:14 pm

Re: PHPUnit question concerning mock objects...

Post by xandrani »

@Weirdan - Yes indeed nbenes is indeed correct, these are both our objects. Thanks to nbenes for pointing that out because I was confused to!

I had a situation where I had a tightly coupled class. The class in question overrode a database class. Writing a unit test for this class made me realised that I should de-couple the database class from the other class.

I updated the original class to use an Attach() member function to attach the database to it.

e.g. Ordinarily the system might have these calls:

Code: Select all

$Classy = new Classy();
$DatabaseObject = new Database();
But in testing we use a mock Database object (we don't want to test an actual database in unit testing):

Code: Select all

$Classy = new Classy();
// Create the mock database object.
$MockDatabaseObject = $this->getMock('Database', array('query'));
// Create the mock return value for Query() thereby bypassing an ACTUAL call to a database object
// - it is good practise to bypass using a real database in unit testing (unless of course you are unit testing the actual
// database object).
              ->with($this->equalTo("whatever result"));
// Attach the mock database object instead of the real database object.
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: PHPUnit question concerning mock objects...

Post by josh »

I try to avoid mock objects, would rather use a stub. I personally find Phpunit's mock objects to be way more robust than simpletest, and yeah like weirdan says that is just example code. By the way why not name your method setDatabase() rather than attach() ??
Forum Contributor
Posts: 268
Joined: Sat May 03, 2008 8:43 am

Re: PHPUnit question concerning mock objects...

Post by koen.h »

Is there a PHP mock implementation that let's you do the given/when/then stuff, in that order?
Post Reply