I'm trying to follow the AAA pattern to write specifications to ClassA
. This class has dependency with ClassB
that will interact with ClassA
as follow:
class ClassA
{
private $objB;
public function __construct(ClassB $objB)
{
$this->objB = $objB;
}
public function doSomething($arg)
{
$val1 = $this->objB->someMethod($arg);
// do something with variable $val1
$this->objB->otherMethodCall();
}
}
And its specification:
class ClassASpec extends ObjectBehavior
{
function let(ClassB $objB)
{
$this->beConstructedWith($objB);
}
function it_should_do_something_cool(ClassB $objB)
{
// Arrange
$objB->someMethod(10)->willReturn(...);
// Act
$this->doSomething(10);
// Assert
$objB->otherMethodCall()->shouldHaveBeenCalled();
}
}
When I run this specification I got an error saying that method ClassB::otherMethodCall()
was not expected to be called, only ClassB::someMethod()
was expected.
If you use this assertion
// Arrange
$objB->someMethod(10)->willReturn(...);
Your double is a mock and, so, is treated as a mock (no shouldHaveBeen
but only shouldBe
)
Here
// Assert
$objB->otherMethodCall()->shouldHaveBeenCalled();
You are treating your object as it is a spy, that's not the case.
Since your double is a mock, you should modify your code as follows
// Arrange
$objB->someMethod(10)->willReturn(...);
// Assert
$objB->otherMethodCall()->shouldBeCalled();
// Act
$this->doSomething(10);
To know the difference between mocks, spies and stubs, please read prophecy and phpspec documentation