2

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.

Tales Santos
  • 232
  • 3
  • 10

1 Answers1

3

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

DonCallisto
  • 29,419
  • 9
  • 72
  • 100
  • Thanks @DonCallisto. I'll modify the code as you suggest. So, it isn't possible to write AAA in the original order when using mocks e spies, write? What I should do is to write Arrange, Assert, Act and Assert in case to verify the return of Act. – Tales Santos Oct 18 '16 at 13:31
  • @TalesSantos I don't know that particular strategy but are you sure that order matters? because, at least in phpspec and as far as I know, a double could not be spy and mock at the same time as they are checked before (mocks) or after (spies) method execution – DonCallisto Oct 18 '16 at 13:39
  • technically the order doesn't matters, but I think that arrange, act and assert is better keep the specifications organized. Anyway, your answer helped me to understand the difference between mocks and spies. Thanks a lot. – Tales Santos Oct 18 '16 at 13:59