我遇到了 Lumen v5.0.10 的问题,让我束手无策。我正在设计一个应用程序,主要使用带有捆绑phpunit
扩展的 TDD。我基本上得到了BindingResolutionException
“App\Contracts\SubscriberInteractionInterface”。这是目录App\Contracts中的一个接口,它在App\Services中有一个实现,注册AppServiceProvider
如下:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
// Owner manager
$this->app->singleton(
'App\Contracts\OwnerInteractionInterface',
'App\Services\OwnerManager'
);
// Subscriber manager
$this->app->singleton(
'App\Contracts\SubscriberInteractionInterface',
'App\Services\SubscriberManager'
);
// dd($this->app->bound('App\Contracts\SubscriberInteractionInterface'));
}
}
我的沮丧是,如果我取消注释函数中的最后一行,那么它表明它App\Contracts\SubscriberInteractionInterface
已被绑定(因此可能会被解决)。
然后我有一个实际上看起来像这样的控制器
class MyController extends Controller {
public function __construct(LoggerInterface $log)
{
$this->log = $log;
}
public function index(Request $request)
{
if (/* Seems to come from owner */)
{
$owners = App::make('App\Contracts\OwnerInteractionInterface');
return $owners->process($request);
}
if (/* Seems to come from subscriber */)
{
$subscribers = App::make('App\Contracts\SubscriberInteractionInterface');
return $subscribers->process($request);
}
}
}
我以这种方式使用它们是因为我只希望实例化相关的一个(如果我对它们进行类型提示,则不会两者都发生),并且它们在它们的构造函数中也都有类型提示的依赖项。
问题是需要的测试路线OwnerInteractionInterface
运行得很好,但需要的测试路线SubscriberInteractionInterface
却没有。实现和接口非常相似,正如我之前展示的,它们都是同时注册的,我可以确认这SubscriberInteractionInterface
是绑定的。事实上,如果我把这条线:
dd(App::bound('App\Contracts\SubscriberInteractionInterface'));
在index()
它的顶部返回true。测试恰好是有序的,这样使用的路径OwnerInteractionInterface
首先运行并且可以很好地解决,然后另一个测试失败并显示BindingResolutionException
. 但是,如果我省略其他测试并只运行那个测试,那么一切都会顺利进行。测试在不同的文件中,我做的唯一设置是为第三方 API 绑定一个模拟,而不是与所示的完全不同的绑定,并且没有任何代码涉及这些类。这是在一个setUp()
函数内完成的,我确保parent::setUp()
在它内调用。
这里发生了什么?是不是绑定一个具体实例会擦除非具体绑定IoC
?还是默认设置允许一些影响从一个测试转移到另一个测试?
我知道我有一个解决方法,但是从不运行完整的测试套件的限制很烦人。如果我直接使用实例而不是从其界面解析它,那么测试似乎会更容易。
另外,有没有人知道检查IoC
可解析绑定的方法?