php-curl icon indicating copy to clipboard operation
php-curl copied to clipboard

Implement interface?

Open Pixelfck opened this issue 9 years ago • 2 comments

It would be wonderful if you could have your cURL class implement some interface.

Right now, if I want to type-hint the type of a class method argument, I'm forced to type hint the concrete class. If the concrete class would implement an interface, I could type-hint the interface instead. If I can type-hint an interface, I can more easily supply a mock object for unit testing purposes.

Pixelfck avatar Apr 27 '16 10:04 Pixelfck

I don't see a problem with implementing an interface, though there are a lot of "magic" methods which wouldn't be covered by it.

I would argue that you probably shouldn't mock the curl class, instead write a wrapper on top of it that encapsulates your business logic, add integration tests for that class and then mock your business class, but that's a topic for another day.

anlutro avatar Apr 27 '16 15:04 anlutro

That's exactly what I do: I've a wrapper that encapsulate the business logic. To separate the concerns and improve testability, I inject the php-curl into the constructor, instead of instantiating it inside the class.

Right now, the constructor has anlutro\cURL\cURL as a type hint, which pretty much forces me to supply an instance of the concrete class anlutro\cURL\cURL. If anlutro\cURL\cURL would implement an interface, I could instead create a mock object for testing, which implements the same interface, thereby testing my class in isolation.

Current situation

<?php # WrapperClass.php
namespace some/space;

use anlutro\cURL\cURL;

class Wrapper
{
    public function __construct(string $foo, int $bar, cURL $curl)
    {
        // ...
    }
}

Proposed situation

<?php # WrapperClass.php
namespace some/space;

use anlutro\cURL\cURLInterface;

class WrapperClass
{
    public function __construct(string $foo, int $bar, cURLInterface $curl)
    {
        // ...
    }
}
<?php # cURL.php
/**
 * PHP OOP cURL
 * 
 * @author   Andreas Lutro <[email protected]>
 * @license  http://opensource.org/licenses/MIT
 * @package  PHP cURL
 */

namespace anlutro\cURL;

/**
 * ...
 */
class cURL implements cURLInterface
{
    \\ ...
}

The interface only needs to define a minimal set of methods; the following would be enough (for the purpose of loosely coupling functionality, while preserving the option to type-hint, even an empty interface would suffice):

<?php # example.php

namespace anlutro\cURL;

interface cURLInterface
{
    public function newRequest($method, $url, $data = array(), $encoding = Request::ENCODING_QUERY);

    public function sendRequest(Request $request);
}

Cheers

Pixelfck avatar Apr 27 '16 16:04 Pixelfck