Skip to content

Add addFactoryToContainer method#17

Merged
Naktibalda merged 2 commits intoCodeception:masterfrom
olexp:add-factory
Oct 16, 2021
Merged

Add addFactoryToContainer method#17
Naktibalda merged 2 commits intoCodeception:masterfrom
olexp:add-factory

Conversation

@olexp
Copy link
Copy Markdown
Contributor

@olexp olexp commented Sep 17, 2021

This allows to mock non-shared services by overriding their factories.

*
* @part services
*/
public function addFactoryToContainer(string $name, $factory): void
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$factory could be documented as * @param string|callable $factory, right?

Could you add a short example and/or a link to some article explaining how using factory helps with testing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. Docblock could be updated for $factory parameter. I didn't do that because other methods don't have params described either.
I can add test to https://github.com/Naktibalda/codeception-laminas-tests similar to https://github.com/Naktibalda/codeception-laminas-tests/blob/master/tests/functional/AddServiceToContainerCept.php.
General principle behind it is that whenever you use ServiceManager#build() to build a service, new service instance is returned. In order to have expected service stub built by the ServiceManager we can return it with help of substitution of factory for the service in tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do that because other methods don't have params described either.

That's because @TavoNiievez went through all methods and replaced @param annotations with scalar typehints.
$factory can't have typehint, so @param provides useful information for IDEs and static analysis tools.

General principle behind it is that whenever you use ServiceManager#build() to build a service, new service instance is returned. In order to have expected service stub built by the ServiceManager we can return it with help of substitution of factory for the service in tests.

I'm not asking for myself, but for people who may want to use it. I tried searching yesterday, but failed to find anything relevant.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example:

$I = new FunctionalTester($scenario);

$foo = \Codeception\Stub::makeEmpty(stdClass::class, ['bar' => 1]);
$I->addFactoryToContainer('foo', fn() => $foo);

$I->amOnPage('/edit');
// EditController
//public function editAction()
//{
//    // $service is a Stub created earlier
//    $service = $this->serviceLocator()->build('foo', ['param1' => 'test']);
//}

More info about shared/non-shared services:
https://docs.laminas.dev/laminas-servicemanager/configuring-the-service-manager/#shared

@Naktibalda Naktibalda merged commit 7423b3b into Codeception:master Oct 16, 2021
@Naktibalda
Copy link
Copy Markdown
Member

Released as 1.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants