Skip to content

Commit

Permalink
Merge pull request #9 from facile-it/test/strategies
Browse files Browse the repository at this point in the history
Test strategies for some edge cases
  • Loading branch information
xzhayon authored Jun 20, 2017
2 parents 2a10f79 + a20e1f2 commit 51895c2
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 65 deletions.
32 changes: 27 additions & 5 deletions src/Moka/Strategy/AbstractMockingStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function build(string $fqcn)
} catch (\Throwable $exception) {
throw new MockNotCreatedException(
sprintf(
'Cannot create mock object for FQCN %s: %s',
'Cannot create mock object for FQCN "%s": %s',
$fqcn,
$exception->getMessage()
)
Expand Down Expand Up @@ -69,6 +69,18 @@ public function get($mock)
return $this->doGet($mock);
}

/**
* @return string
*
* @throws NotImplementedException
*/
public function getMockType(): string
{
$this->verifyMockType();

return $this->mockType;
}

/**
* @param string $fqcn
*/
Expand All @@ -85,14 +97,12 @@ final protected function setMockType(string $fqcn)
*/
final protected function checkMockType($mock)
{
if (!$this->mockType) {
throw new NotImplementedException();
}
$this->verifyMockType();

if (!is_a($mock, $this->mockType)) {
throw new InvalidArgumentException(
sprintf(
'Mock must be of type %s, %s given',
'Mock must be of type "%s", "%s" given',
$this->mockType,
gettype($mock)
)
Expand All @@ -118,4 +128,16 @@ abstract protected function doDecorate($mock, StubSet $stubs);
* @return object
*/
abstract protected function doGet($mock);

/**
* @return void
*
* @throws NotImplementedException
*/
private function verifyMockType()
{
if (!$this->mockType) {
throw new NotImplementedException('Mock type was not defined');
}
}
}
8 changes: 8 additions & 0 deletions src/Moka/Strategy/MockingStrategyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Moka\Exception\InvalidArgumentException;
use Moka\Exception\MockNotCreatedException;
use Moka\Exception\NotImplementedException;
use Moka\Stub\StubSet;

/**
Expand Down Expand Up @@ -38,4 +39,11 @@ public function decorate($mock, StubSet $stubs);
* @throws MockNotCreatedException
*/
public function get($mock);

/**
* @return string
*
* @throws NotImplementedException
*/
public function getMockType(): string;
}
26 changes: 26 additions & 0 deletions tests/AbstractTestClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);

namespace Tests;

abstract class AbstractTestClass implements TestInterface
{
public function isTrue(): bool
{
return true;
}

public function getInt(): int
{
return 1;
}

public function getSelf(): TestInterface
{
return $this;
}

public function throwException()
{
}
}
8 changes: 8 additions & 0 deletions tests/BarTestClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
declare(strict_types=1);

namespace Tests;

class BarTestClass extends AbstractTestClass
{
}
8 changes: 8 additions & 0 deletions tests/FooTestClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
declare(strict_types=1);

namespace Tests;

class FooTestClass extends AbstractTestClass
{
}
8 changes: 4 additions & 4 deletions tests/Proxy/ProxyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Moka\Strategy\MockingStrategyInterface;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
use Tests\TestClass;
use Tests\FooTestClass;

class ProxyTest extends TestCase
{
Expand All @@ -36,7 +36,7 @@ public function setUp()
->willReturn($mock);

$this->proxy = new Proxy(
TestClass::class,
FooTestClass::class,
$this->mockingStrategy
);
}
Expand All @@ -56,10 +56,10 @@ public function testStubAndDecorateSuccess()
public function testServeSuccess()
{
$this->mockingStrategy->method('get')->willReturn(
$this->getMockBuilder(TestClass::class)->getMock()
$this->getMockBuilder(FooTestClass::class)->getMock()
);

$this->assertInstanceOf(TestClass::class, $this->proxy->serve());
$this->assertInstanceOf(FooTestClass::class, $this->proxy->serve());
}

public function testServeFailure()
Expand Down
4 changes: 2 additions & 2 deletions tests/Strategy/IncompleteMockingStrategyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

class IncompleteMockingStrategyTest extends TestCase
{
public function testCheckMockTypeFailure()
public function testGetMockTypeFailure()
{
$strategy = new IncompleteMockingStrategy();

$this->expectException(NotImplementedException::class);
$strategy->get(new \stdClass());
$strategy->getMockType();
}
}
46 changes: 42 additions & 4 deletions tests/Strategy/MockeryMockingStrategyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

namespace Tests\Strategy;

use Mockery\MockInterface;
use Moka\Exception\MockNotCreatedException;
use Moka\Strategy\MockeryMockingStrategy;
use Tests\TestClass;
use Tests\BarTestClass;
use Tests\FooTestClass;
use Tests\TestInterface;

class MockeryMockingStrategyTest extends MockingStrategyTestCase
{
Expand All @@ -15,7 +16,6 @@ public function __construct($name = null, array $data = [], $dataName = '')
parent::__construct($name, $data, $dataName);

$this->setStrategy(new MockeryMockingStrategy());
$this->setMockType(MockInterface::class);
}

public function testBuildEmptyFQCNFailure()
Expand All @@ -32,11 +32,49 @@ public function testBuildParseFailure()
$this->strategy->build('foo bar');
}

public function testBuildMultipleFQCNSuccess()
{
$mock = $this->strategy->build(FooTestClass::class . ', ' . BarTestClass::class);

$this->assertInstanceOf($this->strategy->getMockType(), $mock);
}

public function testBuildMultipleFakeFQCNFailure()
{
$this->expectException(MockNotCreatedException::class);

$this->strategy->build($this->getRandomFQCN() . ', ' . $this->getRandomFQCN());
}

public function testCallMissingMethodFailure()
{
$mock = $this->strategy->build(TestClass::class);
$mock = $this->strategy->build(FooTestClass::class);

$this->expectException(\Throwable::class);
$this->strategy->get($mock)->getSelf();
}

public function testGetFakeFQCNSuccess()
{
$fqcn = $this->getRandomFQCN();
$mock = $this->strategy->build($fqcn);

$this->assertTrue(is_a($this->strategy->get($mock), $fqcn));
}

public function testGetMultipleClassInterfaceSuccess()
{
$mock = $this->strategy->build(FooTestClass::class . ', ' . TestInterface::class);

$this->assertTrue(is_a($this->strategy->get($mock), FooTestClass::class));
$this->assertTrue(is_a($this->strategy->get($mock), TestInterface::class));
}

public function testGetMultipleFQCNPartialSuccess()
{
$mock = $this->strategy->build(FooTestClass::class . ', ' . BarTestClass::class);

$this->assertFalse(is_a($this->strategy->get($mock), FooTestClass::class));
$this->assertTrue(is_a($this->strategy->get($mock), BarTestClass::class));
}
}
66 changes: 49 additions & 17 deletions tests/Strategy/MockingStrategyTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
use Moka\Strategy\MockingStrategyInterface;
use Moka\Stub\StubSet;
use PHPUnit\Framework\TestCase;
use Tests\TestClass;
use Tests\AbstractTestClass;
use Tests\FooTestClass;
use Tests\TestInterface;

abstract class MockingStrategyTestCase extends TestCase
{
Expand All @@ -17,11 +19,6 @@ abstract class MockingStrategyTestCase extends TestCase
*/
protected $strategy;

/**
* @var string
*/
protected $mockType;

/**
* @var StubSet
*/
Expand All @@ -31,28 +28,58 @@ public function setUp()
{
// Mocking a StubSet is way too difficult.
$this->stubs = StubFactory::fromArray([
'isValid' => false,
'isTrue' => false,
'getInt' => 3,
'throwException' => new \Exception()
]);
}

public function testBuildSuccess()
public function testBuildClassSuccess()
{
$mock = $this->strategy->build(FooTestClass::class);

$this->assertInstanceOf($this->strategy->getMockType(), $mock);
}

public function testBuildInterfaceSuccess()
{
$mock = $this->strategy->build(TestInterface::class);

$this->assertInstanceOf($this->strategy->getMockType(), $mock);
}

public function testBuildAbstractClassSuccess()
{
$mock = $this->strategy->build(TestClass::class);
$mock = $this->strategy->build(AbstractTestClass::class);

$this->assertInstanceOf($this->mockType, $mock);
$this->assertInstanceOf($this->strategy->getMockType(), $mock);
}

public function testDecorateSuccess()
public function testBuildFakeFQCNSuccess()
{
$mock = $this->strategy->build(TestClass::class);
$mock = $this->strategy->build($this->getRandomFQCN());

$this->assertInstanceOf($this->strategy->getMockType(), $mock);
}

public function testDecorateSingleCallSuccess()
{
$mock = $this->strategy->build(FooTestClass::class);
$this->strategy->decorate($mock, $this->stubs);
$this->assertSame(false, $this->strategy->get($mock)->isValid());
$this->assertSame(false, $this->strategy->get($mock)->isTrue());

$this->expectException(\Exception::class);
$this->strategy->get($mock)->throwException();
}

public function testDecorateMultipleCallsSuccess()
{
$mock = $this->strategy->build(FooTestClass::class);
$this->strategy->decorate($mock, $this->stubs);
$this->assertSame(3, $this->strategy->get($mock)->getInt());
$this->assertSame(3, $this->strategy->get($mock)->getInt());
}

public function testDecorateFailure()
{
$this->expectException(InvalidArgumentException::class);
Expand All @@ -62,9 +89,9 @@ public function testDecorateFailure()

public function testGetSuccess()
{
$mock = $this->strategy->build(TestClass::class);
$mock = $this->strategy->build(FooTestClass::class);

$this->assertInstanceOf(TestClass::class, $this->strategy->get($mock));
$this->assertInstanceOf(FooTestClass::class, $this->strategy->get($mock));
}

public function testGetFailure()
Expand All @@ -74,13 +101,18 @@ public function testGetFailure()
$this->strategy->get(new \stdClass());
}

public function testGetMockTypeSuccess()
{
$this->assertInternalType('string', $this->strategy->getMockType());
}

protected function setStrategy(MockingStrategyInterface $strategy)
{
$this->strategy = $strategy;
}

protected function setMockType(string $fqcn)
protected function getRandomFQCN()
{
$this->mockType = $fqcn;
return 'foo_' . rand();
}
}
Loading

0 comments on commit 51895c2

Please sign in to comment.