Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting started with "Enhance PHP"

I am looking to incorporate a testing framework into a project I am building and came across Enhance PHP which I like but I am having some difficulty finding relevant information on-line since "enhance php" is such a commonly used phrase.

Has anyone worked with this framework that might be able to point me toward some helpful guide? Have you worked with a unit test framework that you think is amazingly better?

Thanks in advance.

In response to Gotzofter, this is the class to be tested:

<?php
include_once('EnhanceTestFramework.php');

class ExampleClass
{
    private $OtherClass;

    function __construct($mock = null)
    {
        if ($mock == null)
            $this->OtherClass = new OtherExampleClass();
        else
            $this->OtherClass = $mock;
    }

    public function doSomething()
    {
        return $this->OtherClass->getSomething(1, 'Arg2');
    }
}

class OtherExampleClass
{
    public function getSomething()
    {
        return "Something";
    }
}

class ExampleClassTests extends \Enhance\TestFixture
{
    public function setUp() 
    {
    }

    public function tearDown()
    {
    }

    public function verifyWithAMock() 
    {
        $mock = \Enhance\MockFactory::createMock('OtherExampleClass');
        $mock->addExpectation(
            \Enhance\Expect::method('getSomething')
                ->with(1, 'Arg2')
                ->returns('Something')
                ->times(1)
            );
        $target = new ExampleClass($mock);
        $result = $target->doSomething();
        \Enhance\Assert::areIdentical("Something", $result);

        $mock->verifyExpectations();
    }
}

\Enhance\Core::runTests();

look at my constructor for ExampleClass.

Because enhance-php's site example injects the $mock object by calling new ExampleClass($mock), I am forced to change my ExampleClass constructor to handle a $mock as an input parameter.

Do I have to handle this for all classes that I want to subject to unit testing with the framework?

Thanks.

like image 555
Aaron Luman Avatar asked Dec 05 '11 22:12

Aaron Luman


3 Answers

This:

function __construct()
{
   $this->OtherClass = new OtherExampleClass;
}

Should be:

function __construct($otherClass)
{
   $this->OtherClass = $otherClass;
}

Your mock is never injected at this point in your test:

   $target = new ExampleClass($mock);
like image 73
Gutzofter Avatar answered Oct 24 '22 02:10

Gutzofter


One thing I would recommend no matter what testing framework you are using is type-hinting against the expected class, or interface.

<?php
class ExampleClass
{
  private $OtherClass;  // OtherClass instance

  public function __construct(OtherClass $OtherClass=null)
  {
      // ...
  }
}

I'm no di expert, but I don't see the problem in letting each class call new if an instance isn't provided for a particular dependency. You could also of course take the approach where you use setter methods to configure dependencies.

<?php
class class ExampleClass
{
  private $OtherClass;  // OtherClass instance

  public function setOtherClass(OtherClass $OtherClass)
  {
    $this->OtherClass = $OtherClass;
  }
}

It is lame that the ExampleClass in the sample code doesn't even define the doSomething method from the ExampleDependencyClassTests, but if I understand correctly it looks like Enhance PHP is not forcing you to take a particular style of dependency injection. You can write the test class however you want, so for example if you took the setter method approach I mentioned above, you could change the example mock code to

<?php
class ExampleDependencyClassTests extends \Enhance\TestFixture
{
    public function verifyWithAMock() 
    {
        $mock = \Enhance\MockFactory::createMock('ExampleDependencyClass');
        $mock->addExpectation(
            \Enhance\Expect::method('getSomething')
            ->with(1, 'Arg2')
            ->returns('Something')
            ->times(1)
        );
        $target = new ExampleClass();
        $target->setExampleDependencyClass($mock);
        $result = $target->doSomething();
        $mock->verifyExpectations();
    }
}

Of course it would probly make sense to make the appropriate revisions to the ExampleClass!

<?php
class ExampleClass
{
    private $ExampleDependencyClass;

    public function addTwoNumbers($a, $b)
    {
        return $a + $b;
    }

    public function setExampleDependencyClass(
        ExampleDependencyClass $ExampleDependecyClass
    ) {
        $this->ExampleDependecyClass = $ExampleDependecyClass;
    }

    public function doSomething($someArg)
    {
        return 'Something';
    }
}

I've worked with PHPUnit quite a bit, and honestly you'll have to face the same challenges with Mocks there. My 2 cents, try to model your tests without Mocks if possible ;)

like image 1
quickshiftin Avatar answered Oct 24 '22 02:10

quickshiftin


There is a tutorial on NetTuts titled Testing Your PHP Codebase With Enhance PHP, which will definitely help you to get started.

And there is a Quick Start Guide on Enhance PHP.

like image 1
Fenton Avatar answered Oct 24 '22 04:10

Fenton