Login to bookmark this video
Buy Access to Course
14.

TDD Getter Behaviour

|

Share this awesome video!

|

Lucky you! You found an early release chapter - it will be fully polished and published shortly!

This Chapter isn't quite ready...

Get Notified About this Course!

We will send you messages regarding this course only
and nothing else, we promise.
You can unsubscribe anytime by emailing us at:
privacy@symfonycasts.com

We have our first test for TranslatedObject, which is passing. When we wrote that test, we didn't truly use Test Driven Development, because the logic already existed - we just confirmed it with a test.

True TDD is when you write a test for something that doesn't yet exist, in a way you want it to work, see it fail, then write the code to make it pass. So, let's do that now!

Another Test

We want TranslatedObject::__call() to first check if there's a getter available. When calling title(), if this method doesn't exist on the inner object, try and call getTitle().

In TranslatedObjectTest, below our first test, create a new one public function testCallUsesGetterIfAvailable():

// ... lines 1 - 7
class TranslatedObjectTest extends TestCase
{
// ... lines 10 - 20
public function testCallUsesGetterIfAvailable()
{
// ... lines 23 - 25
}
}
// ... lines 28 - 45

Inside, our setup will be the same so copy the $object = from the test above and paste it here:

// ... lines 1 - 7
class TranslatedObjectTest extends TestCase
{
// ... lines 10 - 20
public function testCallUsesGetterIfAvailable()
{
$object = new TranslatedObject(new ObjectForTranslationStub());
// ... lines 24 - 25
}
}
// ... lines 28 - 45

Now for the assertion. In our stub object, we have a prop3 property with a getter: getProp3(). So, if calling the prop3() method on our wrapper (without the get) we want to forward this call to getProp3() on the inner object.

$this->assertSame('value3', $object->prop3()) - that's it!

// ... lines 1 - 7
class TranslatedObjectTest extends TestCase
{
// ... lines 10 - 20
public function testCallUsesGetterIfAvailable()
{
// ... lines 23 - 24
$this->assertSame('value3', $object->prop3());
}
}
// ... lines 28 - 45

At your terminal, run the tests with:

symfony php vendor/bin/phpunit object-translation-bundle/tests

This test fails - but that's what we expect! This basically matches the error we're seeing from Twig. Now we need to write the code to make it pass.

Implementing the Logic

In TranslatedObject::__call(), at the beginning of the method, set $method = $name. Now, add a check: if (!method_exists($this->_inner, $name)). Inside, write $method = 'get'.ucfirst($name) - this capitalizes the first letter of the name and prepends get:

// ... lines 1 - 9
final class TranslatedObject
{
// ... lines 12 - 19
public function __call(string $name, array $arguments): mixed
{
$method = $name;
if (!method_exists($this->_inner, $method)) {
$method = 'get'.ucfirst($name);
}
// ... lines 27 - 28
}
// ... lines 30 - 39
}

Below, in the return, change $name to $method. That should be it!

// ... lines 1 - 9
final class TranslatedObject
{
// ... lines 12 - 19
public function __call(string $name, array $arguments): mixed
{
// ... lines 22 - 27
return $this->_inner->$method(...$arguments);
}
// ... lines 30 - 39
}

Verifying the Behavior

Back in your terminal, run the tests again:

symfony php vendor/bin/phpunit object-translation-bundle/tests

Green! TDDS - Test Driven Development Success!

Note that both our tests pass - that's important as it means we didn't break any existing functionality.

Now for the true test - let's see if this fixes our Twig issue.

In your browser, on the article page that has the error, refresh... and perfect! Error's gone. The title and content are properly being pulled from the underlying object.

There's likely more edge cases we need to consider, but this is a great start. Now that we have this test, if we do find an edge case, we can add a test for it, see it fail, then implement the logic to make it pass. TDD Goodness!

Next, let's again use TDD to bang out a feature - the actual object translations!