1

I have a simple console application which uses Autofac as IoC container.

class Program
{
    static IContainer container;

    static void Main(string[] args)
    {
        container = Configure();
        Run();
    }

    private static void Run()
    {
        using (var scope = container.BeginLifetimeScope())
        {
            var t = scope.Resolve<ITest1>();
            var s = t.TestMethod1("");
            Console.WriteLine(s);
        }
    }

    private static IContainer Configure()
    {
        var builder = new ContainerBuilder();

        builder.RegisterType<TestClass1>()
                .As<ITest1>();

        builder.RegisterType<TestClass2>()
                .As<ITest2>();

        return builder.Build();
    }
}

The application calls the method "TestMethod1" in "TestClass1".

public interface ITest1
{
    string TestMethod1(string s);
}

public class TestClass1 : ITest1
{
    ITest2 f;

    public TestClass1(Func<ITest2> test2Factory)
    {
        f = test2Factory();
    }

    public string TestMethod1(string s)
    {
        var r = string.Empty;

        r = f.TestMethod2(s);
        r += ":TestMethod1";

        return r;
    }
}

TestClass1 has a dependency on TestClass2 which declares a delegate factory for Autofac to use with the TestClass1 constructor.

public interface ITest2
{
    string TestMethod2(string s);
}

public class TestClass2 : ITest2
{
    public delegate TestClass2 Factory();

    public virtual string TestMethod2(string s)
    {
        return ":TestMethod2";
    }
}

This all works as expected - Autofac resolves the TestClass2 dependency, and I get the output ":TestMethod2:TestMethod1".

Now I want to mock TestClass2 using Moq and the Autofac.Extras.Moq extensions. I add the following method to the console application, and call it from the Program Main method.

private static void Test()
{
    using (var mock = AutoMock.GetLoose())
    {
        mock.Mock<TestClass2>()
        .Setup(t => t.TestMethod2(""))
        .Returns(":NOT_TEST_METHOD2");

        var s = mock.Create<TestClass1>();
        var r = s.TestMethod1("cheese");
        Console.WriteLine(r);
    }
}

Now I get the output ":TestMethod1" when I expect ":NOT_TEST_METHOD2:TestMethod1". It seems the mock has not been called. This is confirmed when I step through the code.

I have also tried resolving the mock using mock.Provide(), as has been suggested elsewhere (see below). Still no luck.

var wc = Moq.Mock.Of<TestClass2>(f => f.TestMethod2("") == ":NOT_TEST_METHOD2");
Func<string, ITest2> factory = x => wc;
mock.Provide(factory);

This seems like a really simple scenario but I've not found a working answer anywhere. Can anyone see what I'm doing wrong? Thanks for any help!

weirdpie
  • 11
  • 1

2 Answers2

0

I don't use the AutoMock support, but I do know my Autofac, so I can give it a shot.

It looks like TestClass1 takes an ITest2 and not a TestClass2 in its constructor, I'm guessing if you switched to this:

mock.Mock<ITest2>()
    .Setup(t => t.TestMethod2(""))
    .Returns(":NOT_TEST_METHOD2");

...then it might work.

Travis Illig
  • 23,195
  • 2
  • 62
  • 85
0

Thanks Travis. Your suggestion didn't work for me, but it made me think about the issue differently and taking a step back made me realise I was looking for a complex solution where one wasn't required. Namely, that only Moq was needed, Autofac AutoMock extensions were not. The following code worked:

private static void Test()
{
    Func<ITest2> func = () =>
    {
        var x = new Mock<ITest2>();
        x.Setup(t => t.TestMethod2("")).Returns(":NOT_TEST_METHOD2");
        return x.Object;
    };

    var s = new TestClass1(func);
    var r = s.TestMethod1("");
}

The question was answered by this post Using Moq to Mock a Func<> constructor parameter and Verify it was called twice.

weirdpie
  • 11
  • 1