Reputation: 83
I have already encountered this thread, but my use case is slightly different since I don't create a new instance of the service I am gonna test, but get the instance and all its dependencies from a container. My question is how to get to a specific case in that switch-case logic?
Implementations:
interface MessageInterface { * my code * }
class MyFirstClass extends Message { * my code * }
class MySecondClass extends Message { * my code * }
class MyThirdClass extends Message { * my code * }
abstract class Message implements MessageInterface { * my code * }
public function sendMessage(MessageInterface $message) : void
{
var_dump(get_class($message));
// output: "Mock_MyFirstClass_c5f215a6"
var_dump( MyFirstClass::class);
// output: "My\Namespace\MyFirstClass"
switch (get_class($message)) {
case MyFirstClass::class:
**how to get here?**
$message->render();
break;
case MySecondClass::class:
break;
case MyThirdClass::class:
break;
}
}
Test:
public function setUp() : void
{
parent::setUp();
$this->myService = $this->container->getMyService();
}
public function testSendMessage() : void
{
$message = $this->createMock(MyFirstClass::class);
$message->expects($this->once())->method("render");
$this->myService->sendMessage($message);
}
Upvotes: 0
Views: 1115
Reputation: 17417
The short version is that if you're using createMock
, you won't be able to use get_class
. The mocks returned extend the class provided rather than implementing it directly, and doing a direct string-comparison on the class names isn't going to work.
Depending on the complexity of your message class, or if you can't modify your service, you might want to consider using a fixture instead. That is, just call $message = new MyFirstClass()
rather than mocking it. Do you consider the message to be a dependency of the service, or it is simply an object to be processed? A fixture could make more sense for the second case. There is some much more detailed discussion about this on Martin Fowler's site, here: https://martinfowler.com/articles/mocksArentStubs.html
Alternatively, if you can modify the service, then you'll be able to use instanceof
instead, since that will work with subclasses.
Rather than
switch (get_class($message)) {
case MyFirstClass::class:
...
it'd be
if ($message instanceof MyFirstClass::class) {
...
Upvotes: 1