[英]Using dependency injection in SpecFlow step-file
我們使用 Unity 作為我們的依賴注入框架。
我想創建一個驗收測試並需要一個 DossierService 實例。
不幸的是,我收到以下異常:
BoDi.ObjectContainerException: '接口無法解析 [...]'
[Binding]
public class DossierServiceSteps : BaseSteps
{
private IDossierService dossierService;
public DossierServiceSteps(IDossierService dossierService)
{
this.dossierService = dossierService;
}
}
提前致謝
編輯:我試過像這樣使用SpecFlow.Unity
:
public static class TestDependencies
{
[ScenarioDependencies]
public static IUnityContainer CreateContainer()
{
var container = UnityConfig.GetConfiguredContainer();
container.RegisterTypes(typeof(TestDependencies).Assembly.GetTypes().Where(t => Attribute.IsDefined(t, typeof(BindingAttribute))),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled);
return container;
}
}
在UnityConfig
,類型已正確注冊
container.RegisterType<IDossierService, DossierService>(new InjectionConstructor(typeof(IDataService), typeof(IDossierRepository), typeof(IDbContext), true));
但我仍然得到同樣的例外。 當我在TestDependencies
的CreateContainer()
方法的TestDependencies
放置一個斷點時,它不會中斷......
我們通過實現SpecFlow RuntimePlugin解決了這個問題。 在我們的例子中是 Castle.Windsor,但原理是一樣的。 首先,您定義覆蓋默認 SpecFlow Instance Resolver 的插件:
public class CastleWindsorPlugin : IRuntimePlugin
{
public void Initialize(RuntimePluginEvents runtimePluginEvents, RuntimePluginParameters runtimePluginParameters)
{
runtimePluginEvents.CustomizeScenarioDependencies += (sender, args) =>
{
args.ObjectContainer.RegisterTypeAs<CastleWindsorBindingInstanceResolver, IBindingInstanceResolver>();
};
}
}
在CastleWindsorBindingInstanceResolver
我們需要實現單個方法: object ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer);
. 這個類包含容器和解析(在你的例子中是IUnityContainer
。我建議注入到 self 的容器實例中,這樣你就可以將IUnityContainer
的實例注入到 SpecFlow 綁定類中)
這個插件需要在單獨的程序集中,你將它加載到你的測試項目中,就像這樣調整app.config
:
<specFlow>
<plugins>
<add name="PluginAssemblyName" path="." type="Runtime" />
</plugins>
...
</specFlow>
博迪究竟是什么? 我找不到任何有用的信息..
BoDI 是一個非常基本的依賴注入框架,它包含在 Specflow 中。 你可以在這里找到它的代碼庫。
見該條目從SpecFlow的創造者,卡斯珀·納吉(重點煤礦)的博客:
SpecFlow 使用稱為 BoDi 的特殊依賴注入框架來處理這些任務。 BoDi 是 GitHub 上提供的可嵌入開源迷你 DI 框架。 雖然它是一個通用的 DI,但它的設計和特性是由 SpecFlow 的需求驅動的。 到 SpecFlow 項目開始時,NuGet 還不存在,因此庫是通過 zip 下載分發的,並且必須手動引用程序集。 因此,我們希望將 SpecFlow 運行時保留為單一程序集庫。 為此,我們需要一個小型且可以作為源代碼嵌入的 DI 框架。 我們也不想使用眾所周知的 DI 框架,因為它可能會導致與您自己的項目使用的框架版本沖突。 這促使我創建了 BoDi。
您可以在此處找到如何在 BoDI 中注冊類型和接口的示例:
[Binding]
public class DependencyConfiguration
{
private IObjectContainer objectContainer;
public DependencyConfiguration(IObjectContainer objectContainer)
{
this.objectContainer = objectContainer;
}
[BeforeScenario(Order = 0)]
public void ConfigureDependencies()
{
if (...)
objectContainer.RegisterTypeAs<RealDbDriver, IControllerDriver>();
else
objectContainer.RegisterTypeAs<StubDbDriver, IControllerDriver>();
}
}
但是,請注意(用 Gáspár Nagy 的話說):
雖然可以自定義 SpecFlow 使用的依賴注入,但它已經突破了 BoDi 的能力邊界。 更好的選擇是為此使用更復雜的 DI 框架。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.