Elad Lachmi
Elad Lachmi

Reputation: 10581

Mock implementation for use in automatic UI testing

I am working on adding basic automatic UI tests to the block of unit tests we run with each nightly build. We used MSTest coded UI and created a script.

The code-behind is dependent upon IClientManager which both the real manager and mock implement. My problem is that I don't know how to switch automatically between the real and mock implementations inside the button click handler, when running a test.

My two other constraints are that I can't have a dependency on the mock assembly in the code-behind and that I can't use a DI framework, since the client is "security conscious" and getting a framework approved might take months.

Is there any way of doing this manually, and hopefully, not a bigger problem than the problem I am looking to solve?

Thank you!

Upvotes: 2

Views: 572

Answers (1)

Jon Erickson
Jon Erickson

Reputation: 114956

You could build your own simple object container if you can't use a third party one (which is silly but I understand, I've been there before)

here is something that I whipped up that could get you started... haven't tested it and it is really rough, but hopefully you get the idea

public static class ObjectFactory
{
    static IDictionary<Type, object> _factory = new Dictionary<Type, object>();

    public static void Register<T>(Func<T> builder)
    {
        if (_factory.ContainsKey(typeof(T)))
            _factory[typeof(T)] = builder;
        else
            _factory.Add(typeof(T), builder);
    }

    public static T GetInstance<T>()
    {
        if (_factory.ContainsKey(typeof(T)))
            throw new ArgumentException(string.Format("Type <{0}> not registered in ObjectFactory", typeof(T).Name));

        return ((Func<T>)_factory[typeof(T)])();
    }
}

public interface IClientManager { }
public class RealClientManager : IClientManager { }
public class MockClientManager : IClientManager { }

public class MyView
{
    public MyView()
    {
        // probably better to do this registry in some sort of application initialization
        ObjectFactory.Register<IClientManager>(() => new RealClientManager());
    }

    public void SomeMethodThatNeedsClientManager()
    {
        var clientManager = ObjectFactory.GetInstance<IClientManager>();
    }
}

public class MyTester
{
    [TestMethod()]
    public void SomeTest()
    {
        var view = new MyView();

        // swap the client manager in the test
        ObjectFactory.Register<IClientManager>(() => new MockClientManager());

        // Asserts
    }
}

you can see that if you've used StructureMap or some other DI container before they do a lot of the same thing with a lot of added niceties such as traversing your object graph and registering objects automatically based on conventions, managing object lifecycles, scoping of containers, etc... a lot of this stuff you could implement yourself too... but you should just really used a tried and true solution such as StructureMap

Upvotes: 3

Related Questions