【发布时间】:2015-06-21 23:18:43
【问题描述】:
我遇到了 Lumen v5.0.10 的问题,让我束手无策。我正在设计一个应用程序,主要使用捆绑了phpunit 扩展的TDD。我基本上得到了“App\Contracts\SubscriberInteractionInterface”的BindingResolutionException。这是目录 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 的可解析绑定的方法吗?
【问题讨论】:
-
似乎其他人在 Laravel 中遇到了与单元测试类似的问题,只是他们在 issue 中讨论的 Eloquent 事件中遇到了这些问题。
-
这个问题似乎与 Lumen 如何在
tearDown()和setUp()的TestCase方法中销毁和重新设置应用程序实例有关。第一次工作正常,但每隔一段时间就不太对劲了。在后续测试中也可以使用OwnerInteractionInterface观察到该问题。目前的解决方法是一次只运行 一个 测试。
标签: php laravel-5 ioc-container lumen