WorkHabit Blogs

WORKHABIT LABS

Mock function testing in Drupal

by Aaron Stewart Published: April 24th, 2008
Tagged:

Talking with one of my coworkers yesterday, we found ourselves in need of testing a drupal module in isolation.

This module had a few complex elements to it, in addition to the regular drupal node functionality, such as web service calls and permissions checks, which made testing the module itself far too dependent on third party systems, and made testing itself exceptionally brittle.

Introducing PHPMockFunction

I've written a preliminary pass at mocking functions in drupal. This allows you to focus entirely on your module in an isolated container, and allows you to mock up functions (or retain them, for that matter).

Functions can be new, or they can already exist. That's right. You heard me.

Wait, how do you do that?

Through the magic of the PECL runkit extension, one can selectively override certain functions (either native php functions or userspace ones) in certain conditions. This is NEVER something one should do in production, but in a testing environment, it can be an incredibly userful tool.

PHP mock objects have existed in simpletest and PHPUnit for a long while, but I hadn't seen anything that provided the same functionality for php functions.

So we wrote it.

A mock function example:


require_once("PHPMockFunction.php");
require_once("../mymodule.module");

$dbMock = PHPMockFunction::mock('db_query');
$dummyResource = new stdClass();
$dbMock->expects(InvocationRestriction::once())
->with('SELECT name,value FROM {foo}')
->will(WillAction::returnValue($dummyResource);
$dummyArrayResult = array("name" => "foo", "value" => "bar");
$dbFetchArrayMock = PHPMockFunction::mock('db_fetch_array');
$dbFetchArrayMock->expects(InvocationRestriction::atLeast(1))
->with($dummyResource)
->will(WillAction::returnValue($dummyArray));

mymodule_get_foo_results();

What does this mean?

Now you can test your modules without having to rely on the db layer.. True testing in isolation in drupal.

Download PHPMockFunction here and give it a whirl. Feedback is welcome.

I like your API better than

I like your API better than this “project” http://www.phppatterns.com/docs/develop/simpletestmockfunctions

however, what’s nice about the other “project” is that leverages mock_objects that comes w/simpletest so all sorts of expectations and validation come for free.

Are you going to start a project on this somewhere?

Douglas, You've got a point,

Douglas,

You’ve got a point, SimpleUnit’s mock objects support is fairly comprehensive, but when I was first prototyping this it became probitive since simpleunit insists on acting on objects, for which none exist when you’re mocking a function. My original take on this was an attempt to use either of simplemock or phpmock, but it turned out to be a dead end.

I’d like to kick this off as a project; the above was a sample case, and is definitely a work in progress.

I’ve set it up as a project on Google Code. If you’d like, ping me on D.O. and I’ll set you up as a contributor.

-=A

I've set up a project on

I’ve set up a project on google Code:

http://code.google.com/p/php-mock-function

Excellent!

I submitted a patch, as I’m sure you’ve seen. Mailing list? I have lot’s to discuss that would be useful to capture in project archives.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <h3>
  • You can use Markdown syntax to format and style the text.

More information about formatting options

Papernote
Papernote

WorkHabit Labs Archives