Reputation: 6292
So I have done some searching on here but I cannot find the answer...
I have the following class:
class SomeCrmService
{
public function __construct($endpoint, $key)
{
$this->request = new Request($endpoint);
$this->request->setOption(CURLOPT_USERPWD, $key);
$this->request->setOption(CURLOPT_HTTPHEADER, array(
"Content-type : application/json;", 'Accept : application/json'
));
$this->request->setOption(CURLOPT_TIMEOUT, 120);
$this->request->setOption(CURLOPT_SSL_VERIFYPEER, 0);
}
The problem I have is that I wanted to inject Request
so that I could change the library I was using and it would be easier to mock when testing. I needed to pass in the $endpoint
var which could be (customer, contact, etc) so I thought this was the only option to do it like the above. Is there a way to make this code slightly better and inject Request and use a mutator or something to set the $endpoint
var?
Thanks
Upvotes: 2
Views: 721
Reputation: 376
Use the Factory design pattern:
<?php
class RequestFactory {
public function create($endpoint) {
return new Request($endpoint);
}
}
class SomeCrmService
{
public function __construct($endpoint, $key, RequestFactory $requestFactory)
{
// original solution
// $this->request = new Request($endpoint);
// better solution
$this->request = $requestFactory->create($endpoint);
// here comes the rest of your code
}
}
By using the factory design pattern you don't have to extend other classes - because in fact you dont want to extend them. You are not adding new functionality, your desire is to have testable environment).
Upvotes: 2
Reputation: 24689
I would recommend an approach like this, where you extend the third-party Request
class and allow it to accept an $endpoint
along with a getter:
<?php
class EndpointRequest extends Request
{
protected $endpoint;
public function __construct($endpoint, $key)
{
$this->setOption(CURLOPT_USERPWD, $key);
$this->setOption(CURLOPT_HTTPHEADER, array(
"Content-type : application/json;", 'Accept : application/json'
));
$this->setOption(CURLOPT_TIMEOUT, 120);
$this->setOption(CURLOPT_SSL_VERIFYPEER, 0);
}
public function getEndpoint()
{
return $this->endpoint;
}
}
class SomeCrmService
{
public function __construct(EndpointRequest $request)
{
$this->request = $request;
}
}
Upvotes: 2