Bodi Interface Cannot be resolved using SpecFlow

3.8k Views Asked by At

I have searched all over and have found multiple posts about Bodi exceptions in reference to SpecFlow but none of them are with TestStack.White and none of the responses are working in my situation.

I am using the following:

  • SpecFlow 2.4.0
  • TestStack.White(0.13.3)
  • MsTest(1.4.0)
  • Visual Studio 2017(15.9.4)

I am attempting to use an existing interface to convert an Automation Element into a TestStack.White UIItem

    UIItemFactory itemFactory { get; set; }
    ActionListener actionListener { get; set; }
    public UIItemFactoryHelper(UIItemFactory itemFactory, ActionListener actionListener)
    {
        this.itemFactory = itemFactory;
        this.actionListener = actionListener;
    }

    public virtual IUIItem CreateIUIItemFromAutoElement(AutomationElement automationElement)
    {
        var item = itemFactory.Create(automationElement, actionListener);

        return item;
    }

Then I use it like this

    private DataGrid GetGrid(ParameterizedString Id, Window window = null)
    {
        var form = ScenarioContext.Current["activeForm"];
        var tab = ScenarioContext.Current["activeTab"];
        var parent = GetElementParent(form.ToString(), Id.parentLevel, tab.ToString());

        if (window == null)
        {
            window = WindowHelper.GetWindow();
        }
        var parentUIItem = uiItemFactoryHelper.CreateIUIItemFromAutoElement(parent);
        var element = parentUIItem.Get<DataGrid>(SearchCriteria.ByText("DataGrid"));
        return element;
    }

When I run the test I get the following Error

Message: Test method SmokeTests.SmokeTestSpec.SmokeTestsFeature.EditsAreSaved threw exception: BoDi.ObjectContainerException: Interface cannot be resolved: TestStack.White.Factory.UIItemFactory

I have tried registering the container in the ScenarioHooks and registering the interface in a Before Scenario hook. When I do that I get exactly the same thing.

class ScenarioHooks
{
    IObjectContainer objectContainer;
    public XmlHelper xmlHelper { get; set; }
    public ScenarioHooks(XmlHelper xmlHelper, IObjectContainer objectContainer)
    {
        this.xmlHelper = xmlHelper;
        this.objectContainer = objectContainer;
    }
    [BeforeScenario]
    protected void RegisterInterfaces()
    {
        objectContainer.ResolveAll<UIItemFactory>();
    }
}

I have been doing SpecFlow for a long time but I always get stuck with this container injection stuff. I have read the documentation and searched the various sites but I can't get this working.

Any suggestions are welcome. I am totally stumped here.

2

There are 2 best solutions below

1
On BEST ANSWER

BoDi, as every other DI container, can only resolve an interface, when there is a registration for it.

To get an instance of the UIItemFactory interface, you have to register an implementation.

In your RegisterInterfaces method you are not registering the interface, you are resolving it. You have to change the line objectContainer.ResolveAll<UIItemFactory>() to objectContainer.RegisterTypeAs<THE_IMPLEMENTATION, UIItemFactory>()

0
On

In case someone is here for the TestStack.White problem of converting an Automation Element to a UIItem it is over complicated in my question.

It turns out you can do this implicitly by doing the following.

    public virtual IUIItem CreateIUIItemFromAutoElement(AutomationElement automationElement)
    {
        var element = new UIItem(automationElement, new NullActionListener());
        return element;
    }

You can have a nulled action listener and just create the new UIItem passing in the AutomationElement. That will implicitly call the UIItemFactory.Create method removing the need to register the interface for an explicit call.