Skip to content

Instantly share code, notes, and snippets.

@alganet
Created March 27, 2012 16:57
Show Gist options
  • Save alganet/2217907 to your computer and use it in GitHub Desktop.
Save alganet/2217907 to your computer and use it in GitHub Desktop.
Next-gen mocks and stubs for PHP 5.4
<?php
use FooBar\Test\Mock;
// In the sample below, $mock expects the method "sayHelloTo" to be called one time
// with the parameter $name equals "Alexandre" and return "Hello Alexandre"
$mock = (new Mock)([
'sayHelloTo' => function($name="Alexandre") {
return "Hello Alexandre";
}
]);
<?php
use FooBar\Test\Stub;
// In the sample below, $stub acts as a stub. Pretty much self-explained.
$stub = (new Stub)([
'sayHelloTo' => function($name) {
echo "Hello $name";
}
]);
$stub->sayHelloTo("Alexandre"); //Hello Alexandre

How it works?

It's not implemented yet. Just an idea. I'll explain every bit of it:

  • Before PHP 5.4 we couldn't do something like new bla->foo directly. Now we can do (new bla)->foo.
  • Assuming (new Stub) returns an instance of Stub and that class implements __invoke, we can automatically chain a invoke call on it, like '(new Stub)()'. This is equivalent to $s = new Stub; $s->__invoke();. Just a syntactic sugar.
  • Arrays in PHP 5.4 can be declared as ['foo'=>'bar']. This is the only argument __invoke from Stub receives.
  • Closures can be bound dynamically in PHP 5.4, so we could even use $this inside a stub.
  • We can read the default parameters from closures using Reflection. That way we could use them as expectations. Executing the function gives us the expected return.
@marcelomx
Copy link

Gostei dessa sintaxe. E mocks que implementam interfaces (classes/objetos), tem algum rascunho? Penso em algo assim:

$mock = (new Mock('MockableClass'))([
'sayHelloTo' => function($name = 'Alexandre') {
return "Hello Alexandre";
}
]);

$mock = (new Mock($mockableObject))([
'sayHelloTo' => function($name = 'Alexandre') {
return "Hello Alexandre";
}
]);

@marcelomx
Copy link

Agora que percebi que tem um fork exatamente com essas minhas indagações, mas com a implementação recebendo a classe a ser "mockada" no metodo __invoke, o que faz mais sentido mesmo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment