-
Hello! public function __construct(
EnterpriseDispatcherServiceInterface $service, string $name, string $url, string $login, string $password, bool $enabled = true
)
{
$this->name = $name;
$this->url = $url;
$this->login = $login;
$this->password = $password;
$this->solidcpLoginId = $service->getEnterpriseDispatcherRealUserId($url, $login, $password);
$this->enabled = $enabled;
$this->solidcpServers = new ArrayCollection();
$this->recordEvent(new Event\EnterpriseDispatcherCreated($this));
} It's a service itself that communicates with another server: final readonly class EnterpriseDispatcherService implements EnterpriseDispatcherServiceInterface
{
public function __construct(
private EsUsers $esUsers
) {}
public function getEnterpriseDispatcherRealUserId(string $url, string $login, string $password): int
{
$this->esUsers->initManual($url, $login, $password);
try {
$result = $this->esUsers->getUserByUsername($login);
} catch (\Exception $e) {
throw new \DomainException("Soap execution error (Code: {$e->getCode()}, Message: {$e->getMessage()})", $e->getCode(), $e);
}
if ($result['IsPeer']) {
throw new \DomainException("This Login {$login} is Peer. Please use a real User, not Peer");
}
return (int)$result['UserId'];
}
} To mock it without Symfony complaining: final class EnterpriseDispatcherServiceMock implements EnterpriseDispatcherServiceInterface
{
public function getEnterpriseDispatcherRealUserId(string $url, string $login, string $password): int
{
return 1001;
}
} In some of these mocks, I add the ability to dynamically substitute values to simulate different responses from the external service. Then, I add the corresponding entry in services:
_defaults:
autowire: true
App\Service\EnterpriseDispatcherService:
public: true
class: App\Tests\Mock\EnterpriseDispatcherServiceMock As a result, the code grows catastrophically. If I need to test 20 services, I have to create 20 interfaces, 20 mock classes, and specify 20 entries in UPD: Symfony v6.4.7 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 9 replies
-
It's because your code does not follow SOLID, therefore difficult to mock. In the constructor :
More on https://en.wikipedia.org/wiki/SOLID HTH |
Beta Was this translation helpful? Give feedback.
I personally find that including any arguments in an entity constructor needlessly complicates everything. You also seem to use a service inside of your entity, which is not great. I would simply suggest creating your entity through a factory instead, which would give you yet another service.
As for mocking, I do something similar in a lot of our tests and I generally find that booting the container, and only booting it, should allow you to replace services. If a service cannot be replaced it means it was already used in something when the container started, which could've happened if you say, made a request in the test case.
Example from one of our WebTestCase tests below.