dimanche 18 octobre 2015

Easy way to allow client to switch between instantiating a test "mock" controller object and real controller object?

So in PHP, I have a "real controller" which queries a web service and returns in this case some user information:

class UserController implements IUserController
{
    public $user;

    function __construct() {
        $this->user = new User();

   }

   public function login($user_name, $password)
   {

        try
        {
            #- Loading the WSDL document
               $client = new SoapClient(Common::$WEB_SERVICE);

            #- Calling the RPC method
               $result = $client->login($user_name,$password);

               $xml=simplexml_load_string($result);

                $this->user->is_authenticated = true;
                $this->user->site_id = $xml->SiteID;
               }

        }
        catch(Exception $e)
        {
            echo 'Caught exception:  ', $e->getMessage(), '\n';
        }

       return $this->user;

   }
}

`

I created a mock test class equivalent of the above as follows:

class UserControllerTest extends UserController implements IUserController
{

   public function login($user_name, $password)
   {
        $this->user->site_id = 1234;
        $this->user->first_name = 'john';
        $this->user->last_name = 'doe';
        $this->user->is_authenticated = true;
        //var_dump($this);

       return $this->user;
   }
}

So now my client needs an easy way to switch between the 2 classes, whether I want to test production or the development environment. I am using the following mechanism of defining a global variable called $USE_TEST_DATA; however as you can see the client has to explicitly call one or the other classes to instantiate; this seems very tedious to litter the code with such logic:

$blah = ($USE_TEST_DATA ? new UserControllerTest() : new UserController());
$blah->login('john','john');

What is the "right" way of doing this, adhering to design patterns? I know this can be done with a factory class and that conditional logic is in the factory class and the static method simply returns one or the other object; but this seems like a waste to have a factory class that does nothing but those few lines.

Thanks for design input,

Aucun commentaire:

Enregistrer un commentaire