nette / schema

📐 Validating data structures against a given Schema.
https://doc.nette.org/schema
Other
886 stars 26 forks source link

Make processor class non-final so it can easily be mocked in unit tests #67

Open gauthierm opened 3 months ago

gauthierm commented 3 months ago

The Processor class is marked as final and this makes it difficult to mock in unit tests. In a unit test, I want to hard-code the result of the processing with fixture data as I don't want to test nette/schema, I want to test my code. This is typically done with a mocking library like Mockery, but because the class is final this is not easy to do cleanly.

<?php
class ContentParserTest extends TestCase
{
    #[Test]
    public function parsesNestedContentFields(): void
    {
        $factory = Mockery::mock(Factory::class);
        $processor = Mockery::mock(Processor::class);

        $parser = new ContentParser($processor, $factory);

        ... other test stuff
    }
}

This results in:

Mockery\Exception: The class \Nette\Schema\Processor is marked final and its methods cannot be replaced. Classes marked final can be passed in to \Mockery::mock() as instantiated objects to create a partial mock, but only if the mock is not subject to type hinting checks.

Alternatively, consider making an interface for the Processor, leave the Processor class as final and implement the interface. That way unit tests and methods can use the interface and you can still prevent subclassing.