I'm attempting to write a spec test for a class which contains a doctrine DBAL queryBuilder.
Please tell me if I'm totally missing the point of mocking, I understand that there's the phrase "don't mock tested classes" but not sure how this applies in this context.
Here's the class code:
// Doctrine Connection Class creating QueryBuilder class
$queryBuilder = $this->conn->createQueryBuilder();
$queryBuilder->select([
'some',
'field',
'to_get'
]);
$queryBuilder->from('tableName', 'p');
$queryBuilder->innerJoin('p', 'anotherTableName', 'd', 'd.id = :dId');
$queryBuilder->where('p.id = :pId');
$queryBuilder->setParameters([
':dId' => 123,
':pId' => 456,
])
->setMaxResults(1);
$stm = $query->execute();
$result = $stm->fetch(\PDO::FETCH_ASSOC);
This is my (failing) attempt at writing the PHPSPec test for it:
$queryBuilder->select([
'some',
'field',
'to_get'
])->shouldBeCalled()->willReturn($queryBuilder->getWrappedObject());
$queryBuilder->from('tableName', 'p')->shouldBeCalled()->willReturn($queryBuilder->getWrappedObject());
$queryBuilder->innerJoin('p', 'anotherTableName', 'd', 'd.id = :dId')->shouldBeCalled()->willReturn($queryBuilder->getWrappedObject());
$queryBuilder->where('p.id = :pId')->shouldBeCalled()->willReturn($queryBuilder->getWrappedObject());
$queryBuilder->setParameters([
':dId' => 123,
':pId' => 456,
])->shouldBeCalled()->willReturn($queryBuilder->getWrappedObject());
This is the error I'm receiving:
it will handle event
error: Object of class Prophecy\Prophecy\MethodProphecy could not be converted to string in
<<FILEPATH OMITTED>> line 97
Line 97 in this case being the $queryBuilder->from line.
Anyone got any ideas? Thanks in advance!
I would consider not writing a unit test for this, as your test will basically match 1:1 the calls in your method. You just have duplicate code that needs to be changed each time you modify the query.
Maybe instead you want to write a functional test with behat or phpunit. In this test you have to set up a database, e.g. in-memory sqlite, create the schema, add some base data (fixtures), and then perform a query using your code. With this test you will make sure that from a given set of entries in your table you will get the expected result, no matter how you change the method. This test makes the test less reliant on how you write the query and instead focuses on the in- and output.