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

PHPUnit question concerning mock objects...

Postby nbenes » Tue Nov 27, 2007 11:52 am

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: http://www.phpunit.de/pocket_guide/3.2/ ... jects.html, and the excerpt:

Syntax: [ Download ] [ Hide ]

<?php

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.

        $observer->expects($this->once())

                 ->method('update')

                 ->with($this->equalTo('something'));

 

        // Create a Subject object and attach the mocked

        // Observer object to it.

        $subject = new Subject;

        $subject->attach($observer);

 

        // Call the doSomething() method on the $subject object

        // which we expect to call the mocked Observer object's

        // update() method with the string 'something'.

        $subject->doSomething();

    }

}

?>

 


Most of this I understand just fine, but where is this

Syntax: [ Download ] [ Hide ]

$subject = new Subject;

$subject->attach($observer);

 


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.
nbenes
Forum Newbie
 
Posts: 2
Joined: Tue Nov 27, 2007 11:42 am

Postby Weirdan » Thu Nov 29, 2007 12:22 pm

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.
User avatar
Weirdan
Moderator
 
Posts: 5910
Joined: Mon Nov 03, 2003 7:13 pm
Location: Odessa, Ukraine

Re: PHPUnit question concerning mock objects...

Postby xandrani » Fri Apr 08, 2011 10:25 pm

@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:
Syntax: [ Download ] [ Hide ]
$Classy = new Classy();
$DatabaseObject = new Database();
$Classy->Attach($DatabaseObject);
 

But in testing we use a mock Database object (we don't want to test an actual database in unit testing):
Syntax: [ Download ] [ Hide ]
$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).
$MockDatabaseObject->expects($this->once())
              ->method('Query')
              ->with($this->equalTo("whatever result"));
// Attach the mock database object instead of the real database object.
$Classy->Attach($MockDatabaseObject);
 
xandrani
Forum Newbie
 
Posts: 1
Joined: Fri Apr 08, 2011 10:14 pm

Re: PHPUnit question concerning mock objects...

Postby josh » Tue Apr 26, 2011 7:31 pm

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() ??
josh
DevNet Master
 
Posts: 4872
Joined: Wed Feb 11, 2004 4:23 pm
Location: Palm beach, Florida

Re: PHPUnit question concerning mock objects...

Postby koen.h » Wed Apr 27, 2011 2:01 pm

Is there a PHP mock implementation that let's you do the given/when/then stuff, in that order?
koen.h
Forum Contributor
 
Posts: 268
Joined: Sat May 03, 2008 8:43 am


Return to Testing

Who is online

Users browsing this forum: No registered users and 1 guest