Skip to content

PHP testing library focused on testing classes using dummy parameters, using Prophecy.

License

Notifications You must be signed in to change notification settings

Skyree/class-test

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Class test

PHP testing library focused on testing classes mocking all of their constructor parameters, using Prophecy.

The main objective is to make testing a class quicker by automatizing the tested class instantiation with dummy parameters, and retrieve a whole new instance for each test. Particularly useful to test classes with many objects as constructor parameters that you don't want to be executed, such as helpers, loggers, services, repositories, ...

This library is based on the PHP object mocking framework Prophecy, and requires to know how to test with it, learn more about it here

Simple example

class TestSomeClass extends ClassTestCase {
    public function getTestedClassName() {
        return SomeClass::class;
    }
    
    public function getTestedClassConstructorParameters() {
        return [
            SomeRepository::class,
            SomeService::class,
            Logger::class,
            DbInterface::class,
            'someString'
        ];
    }
    
    public function testSomething() {
        // Retrieve a new instance of SomeClass with dummy constructor parameters
        // that can handle any parameters and return null all the time
        $someClass = $this->getTestedClass();
        
        $result = $someClass->doSomething('someText', 3);
        $this->assert(...);
    }
}

Installation

Prerequisites

Requires PHP 5.3.3 or greater and PHPUnit ^4.8.35 or greater

Composer

Run composer command composer require c-malet/class-test

Usage

Test set up

Set up the test class for the tested class as such :

Extend the ClassTestCase class (which extends the PHPUnit TestCase)

class TestSomeClass extends ClassTestCase {}

Implement the two mandatory methods defining the tested class :

public function getTestedClassName() {
    return SomeClass::class; // or the fully qualified class name
}

public function getTestedClassConstructorParameters() {
    return [
        SomeClass::class,
        SomeInterface::class,
        
        // An object can be provided directly, it will be kept unchanged
        $someObject, 
        
        // If you want to provide several instances of the same class,
        // or if you want to force a key to retrieve mocks later on, 
        // simply specify a key
        'Logger1' => LoggerInterface::class, 
        'Logger2' => LoggerInterface::class,
        
        // string, integer, array, ... can still be used directly
        'someString',
        12345,
        
        // If a string would match a class name for instance, you can still
        // force it as a string parameter this way
        'SomeClass' => ClassTestCase::STRING_PARAMETER
    ]
}

Testing

For each test, a whole new instance of the tested class is created and can be retrieved :

$someClass = $this->getTestedClass();

You can override the getTestedClass method in each test case to inform your IDE the class type of $someClass

It returns a "real" instance of the tested class, it is not a mock, and the whole code of this class will be executed.

Contrariwise, every constructor parameter provided that matches an instantiatable class is transformed into a revealed Prophecy, in such a way that they will automatically handle any parameter and always return null by default.

These Prophecy mocks can be retrieved anytime during tests, to do anything you could do with Prophecy alone, using the getMock method, allowing you to override the default dummy set up as needed for your tests.

$this->getProphecy(SomeRepository::class)->someMethod()->shouldBeCalled(1);

Mocks can be retrieved by their class name or by key, as described earlier in the 'Test set up' part

If your IDE fails to resolve the methods from the class name and gives warning, you can also get ProphecyMethod objects this way :

$this->getProphecyMethod(SomeRepository::class, 'someMethod')->shouldBeCalled(1);

If you wish to use the internal mocks container for any other class to mock, for instance mocks you'd want to use in your tested methods, you can also create mocks and dummies that can be retrieved as other mocks with addNewMock or addNewDummy

$this->addNewMock(SomeClassToMock::class);
$this->addNewDummy(SomeClassToDummy::class);
...
$this->getProphecyMock(SomeClassToMock::class)->myMethod()->willReturn(true);

Full example

class TestPizzaCooker extends ClassTestCase {
    public function getTestedClassName() {
        return PizzaCooker::class;
    }
    
    public function getTestedClassConstructorParameters() {
        OvenInterface::class,
        IngredientPicker::class,
        PizzaFolder::class,
        TimerHelper::class
    }
    
    public function testPizzaShouldAlwaysBeBaked() {
        $pizzaCooker = $this->getTestedClass();
        $pizzaCooker->cookPizza('margerhita', 'XL')

        $this->getProphecy(OvenInterface::class)->bake()->shouldHaveBeenCalled(1);
    }
    
    public function testPizzaCalzoneShouldBeFolded() {
        $pizza = $this->getProphecy(OvenInterface::class)->bake()->willReturn(
            $this->addNewDummy(Pizza::class)->reveal()
        );

        // Folder should fold the previously baked pizza 
        $this->getProphecyMethod(FolderInterface::class, 'fold')->with([$pizza->reveal()]);

        $pizzaCooker = $this->getTestedClass();
        $pizzaCooker->cookPizza('calzone')
        
        // A calzone should always be folded
        $this->getProphecy(FolderInterface::class)->bake()->shouldHaveBeenCalled(1);
    }
}

About

PHP testing library focused on testing classes using dummy parameters, using Prophecy.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%