簡體   English   中英

在 SpecFlow 步驟文件中使用依賴注入

[英]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 容器?

提前致謝

編輯:我試過像這樣使用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));

但我仍然得到同樣的例外。 當我在TestDependenciesCreateContainer()方法的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM