I've got Repository classes which implement a specific interface and also extend a base class for the specific database.
base class:
abstract class CouchDB
{
protected $db;
public function __construct(Sag $db)
{
$this->db = $db;
}
private function call_get($url) {...} //this is a wrapper for $db->get()
}
derived class:
class CouchExpression extends CouchDB implements ExpressionInterface
{
public function __construct(Sag $db)
{
parent::__construct($db);
}
}
the spec:
class CouchExpressionSpec extends ObjectBehavior
{
public function let($db)
{
$db->beADoubleOf('\Sag');
$this->beConstructedWith($db);
}
public function it_gets_returned_by_its_id()
{
$this->db->get('...')->willReturn([]);
}
}
When running PHPSpec I get: property db not found
Is there a way to fix this other than setting the property to public
?
After setting it to public
I get: call to a member function willReturn() on a non-object.
So I can't run ->willReturn()
on $this->db
But why? When doing this in the let
method of the test it works. But not all tests do need the same data returned...
How do I get this running?
You can declare your double without the explicit call, like this:
function let(\Sag $db)
{
$this->beConstructedWith($db);
}
Having done this, if you pass a property of the same name to your example, it will be the same instance of the double:
function it_gets_returned_by_its_id($db)
{
$db->get('...')->willReturn([]);
}
Also, by convention let and example methods don't use the public keyword, they'll be public anyway and it reduces noise around your examples.