Reputation: 499
Consider this code:
<?php namespace App\Services;
use App\Services\AnotherService;
class SomeService {
public function someMethod() {
$anotherService = \App::make(AnotherService::class);
}
}
My intention is to get a class object with all its dependencies resolved. But in this specific case, I would like that the object's __construct has been executed as well. I have tried and by code above, the $anotherService object's __construct method is not executed.
Therefore I can achieve what I need by doing -
$anotherService = \App::make(AnotherService::class);
$anotherService->__construct();
Can it be done with single line instead of redundantly each time call construct method after instantiating the object? - Because that is what __construct method is made for - executing automatically. But I have noticed that for some reason Laravel's automatic dependency resolving skips the __construct execution.
Note, that new AnotherService()
is not an option for me, as well as using the __construct
method of SomeService
class. I would like to make an object inside the someMethod
method.
Class AnotherService
currently does not have any dependencies. It has just some random variable updates inside the __construct
, like:
public function __construct() {
$this->varA = true;
$this->varB = 'Some Value';
}
Why do I need to resolve this class (instead of using new AnotherClass()
)? - Simply because I want to test this call in unit tests by mocking it. For that I use this code:
$this->mock(AnotherService::class, function ($mock) {
$mock->shouldReceive('anotherMethod')->andReturn(false);
});
And then finally I have to call the method to check the response:
$anotherService = \App::make(AnotherService::class);//<-- In this moment $varA and $varB are not set because the __construct did not execute!
$response = $anotherService->anotherMethod();
// Assert...
So, in this case, for example, if anotherMethod
would use any of those variables, the tests would be incorrect because their values are not set.
Upvotes: 1
Views: 3179
Reputation: 138
I believe there is either a mistake somewhere in your code or some misunderstanding.
The problem here is not in Laravel. The key here is the usage of Mockery. When creating a simple Mock
for a class, its constructor is not invoked, and it's just a mock. When using $this->mock(...)
, you just bind a concrete instance (mock) in the container. Thus, when calling its make
, that ready mock is returned. Meaning, that __construct
is neither invoked by Mockery, nor by Container.
Upvotes: 0