mardi 2 février 2016

Mock being passed to the constructor of a class instead and the type hinting doesn't like that

Regardless that this is a duplicate of such and such a question all the solutions I have found fall short of the actual issue.

Consider the following:

class MarketHistory {

    ....

    public function __construct(Client $client, EveLogHandler $eveLogHandler) {
        $this->client        = $client;
        $this->eveLogHandler = $eveLogHandler;
    }

    ....
}

type hinting for the win. Ok so whats the mock look like and what are we mocking?

We are mocking the EveLogHandler.

Ok so we do:

class MarketHistoryTest extends \PHPUnit_Framework_TestCase {

    public function getLogMock() {
        return $this->getMockBuilder('EveOnline\Logging\EveLogHandler')
                    ->disableOriginalConstructor()
                    ->getMock();
    }

    ...

    public function testShouldGetAnArrayOfResults() {
        $logMock = $this->getLogMock();

        ....

        $historyDetails = new MarketHistory($client, $logMock);

        ....
    }
}

looks normal .... I mean Im passing and instance of $client, I am passing the log mock every thing seems correct.

The log handler class doesn't even have a constructor but none the less is super basic:

class EveLogHandler {

    public function requestLog($response, $fileName) {
        $streamHandler = new StreamHandler(storage_path($fileName), Logger::INFO);
        $logInstance   = Log::getMonolog();

        $logInstance->setHandlers(array($streamHandler));
        $logInstance->addInfo('Fetched', [$response->getStatusCode(), $response->getBody()->getContents()]);
        $response->getBody()->rewind();
    }

    public function messageLog($message, $fileName) {
        $streamHandler = new StreamHandler(storage_path($fileName), Logger::INFO);
        $logInstance   = Log::getMonolog();

        $logInstance->setHandlers(array($streamHandler));
        $logInstance->addInfo('Message', [$message]);
    }
}

I don't want any of these methods actually running, hence the mock. Ok fabulous - until I get this:

1) MarketHistoryTest::testShouldGetAnArrayOfResults
TypeError: Argument 2 passed to EveOnline\Items\History\MarketHistory::__construct() must be an instance of App\Etis\EveOnline\Logging\EveLogHandler, instance of Mock_EveLogHandler_aed119bd given, called in /Users/Adam/Documents/eve-online/tests/EveOnline/Items/History/HistoryTest.php on line 48

uh ... Mock_EveLogHandler_aed119bd Ok ... What I have read is that this is an extension of the actual class I am mocking so in theory it should be correct.

I do this exact same thing in other tests, I have copied and pasted from them to make sure theres no spelling mistakes. So unless I fail at life, what is going on?

Every answer I have come across tells me to do what I have done in my mock method. So what gives?

Aucun commentaire:

Enregistrer un commentaire