Here is my class:
public function __construct(Manager $moduleManager, Source\Yesno $yesNo)
{
$this->moduleManager = $moduleManager;
$this->yesNo = $yesNo;
}
public function my1()
{
$this->moduleManager->isOutputEnabled('');
$this->yesNo->toOptionArray();
}
public function my2()
{
$this->moduleManager->isOutputEnabled('');
$this->yesNo->toOptionArray();
}
Here is my test:
...
$this->observerMock = $this->getMock(
'path\to\Observer',
null,
[$this->moduleManagerMock, $this->yesNoMock],
'',
true
);
...
public function testMy1()
{
$this->moduleManagerMock->expects($this->exactly(2))->method('isOutputEnabled');
$this->yesNoMock->expects($this->exactly(2))->method('toOptionsArray');
$this->observerMock->my1();
$this->observerMock->my2();
}
Test returns:
Expectation failed for method name is equal to when invoked 2 time(s). Method was expected to be called 2 times, actually called 0 times.
My question is: I have faced with such things few times, but every time I can't understand what is going on. Why first expectation is proper, and 2nd not proper?
Upd.1
I forgot to say that I faced with such situation few times. Here is what I've noticed. Using xDebug I saw that inside test
[this]
[moduleManager] => ModuleManager_Mock_Name_<hash #1>
[yesNo] => YesNo_Mock_Name_<hash #2>
[observerObject] =>
[moduleManager] => ModuleManager_Mock_Name_<hash #1>
[yesNo] => YesNo_Mock_Name_<hash #3> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
moduleManager objects has the same cache inside unittest object and inside observer object. If I apply smth on moduleMatcher - it appear in both places
Hash of $unittest->yesNo differ from $observerObject hash. If I set matcher for some method - it applies only inside unittest class!!!
Why did it happen? How to prevent create different objects
Upd.2 FOUND!
When you create object through object manager
$this->observerMock = $objectManager->getObject(
'Observer',
[
'moduleManager' => $this->moduleManagerMock,
'yesNo' => $this->yesNoMock,
]
);
Variables 'moduleManager' and 'yesNo' should be the same as variables in constructor:
public function __construct(Manager $moduleManager, Source\Yesno $yesNo)
{
$this->moduleManager = $moduleManager;
$this->yesNo = $yesNo;
}
Here is code where phpunit check this:
foreach ($method->getParameters() as $parameter) {
$parameterName = $parameter->getName();
$argClassName = null;
$defaultValue = null;
if (array_key_exists($parameterName, $arguments)) {
$constructArguments[$parameterName] = $arguments[$parameterName];
continue;
}