问题
Is there a way to create a mock class, as opposed to a mock object, with phpunit? I'm looking for a way to do dependency injection without having to explicitly pass every object a class might need to work with in the constructor (or wherever). Something that will return "true" for all of these cases:
public function testAAAA()
{
$foo = $this->getMock('foo', array('bar'));
var_dump(class_exists('foo', false));
var_dump(method_exists('foo', 'bar'));
var_dump(method_exists($foo, 'bar'));
}
This prints:
bool(true)
bool(false)
bool(true)
indicating that while it did successfully create a fake 'foo' class it did not bind a 'bar' method to it.
I am using phpunit 3.7.5.
回答1:
I suspect that you don't actually want to do this (as you can disable constructors and so on with PHPUnit's mockbuilder, see the docs ), but assuming you do want or need to, this should do the trick:
$foo = $this->getMockBuilder('nonexistant')
->setMockClassName('foo')
->setMethods(array('bar'))
->getMock();
var_dump(class_exists('foo', false));
var_dump(method_exists('foo', 'bar'));
var_dump(method_exists($foo, 'bar'));
$cls = new ReflectionClass('foo');
var_dump($cls->hasMethod('bar'));
I'm honestly not sure about the specifics of why you need to specify different names (nonexistant and foo) above, but it seems to have to do with PHPUnit's behavior when the class being mocked doesn't exist yet, and having setMockClassName generate a class extending that class. Or Something. It's probably effectively working around a bug/edge-case -- this is odd usage of the library. You should be able to do the same thing through the getMock
function alone, it's just uglier.
As an aside, it sounds like you should probably get familiar with php's reflection capabilities. It's not the most powerful reflection library out there, but it's pretty nice. I've used it to generate meta-information about required and optional fields for a class based on their constructor arguments and properties for a "model" library, where that meta-information is used to generate forms that accept the correct types of values. That is, generate typed forms without instances of the class the form is for, and without hand-writing a stupid amount of code -- it's about 100 lines in all for the entire feature. Obviously I don't know what you're trying to do, but from the small amount of info in your post, I'd guess it's closer to that type of meta-thing than not.
来源:https://stackoverflow.com/questions/13389449/create-a-mock-class-with-phpunit