devoured elysium
devoured elysium

Reputation: 105227

Why doesn't the following mocking with Ninject.Moq work?

I'm trying to run the following code with Ninject.Moq:

[TestMethod]
public void TestMethod1()
{
    var kernel = new MockingKernel();
    var engine = kernel.Get<ABC>();

   //as I don't need to actually use the interfaces, I don't want
   //to even have to bother about them.

    Assert.AreEqual<string>("abc", engine.ToString());
}

And here is the ABC class definition:

public class ABC {
    IA a;
    IB b;

    public ABC(IA a, IB b)
    {
        this.a = board;
        this.b = war;
    }

    public override string ToString()
    {
        return "abc";
    }
}

I'm getting the following exception:

System.ArgumentException: A matching constructor for the given arguments was not found on the mocked type. ---> System.MissingMethodException: Constructor on type 'AbcProxya759aacd0ed049f3849aaa75e2a7bade' not found.

Upvotes: 1

Views: 1290

Answers (2)

devoured elysium
devoured elysium

Reputation: 105227

Ok, this will make the code work:

[TestMethod]
public void TestMethod1()
{
    var kernel = new MockingKernel();
    kernel.Bind<Abc>().ToSelf();
    var engine = kernel.Get<ABC>();

   //as I don't need to actually use the interfaces, I don't want
   //to even have to bother about them.

    Assert.AreEqual<string>("abc", engine.ToString());
}

One has to bind Abc to itself, otherwise it will also get mocked and Moq only supports mocking parameterless classes, which is not the case.

Upvotes: 3

Ruben Bartelink
Ruben Bartelink

Reputation: 61903

It's a bit like understanding DI in the first place :- small samples don't really get the whole point across.

An automocking container like Ninject.Moq (or similar test infrastructure libraries like AutoFixture) is hard to really explain with a simple example. I'd suggest reading all of Mark Seemann's posts on AutoFixture as a way of getting a feel fro the requirement.

So Ninject.Moq will deal with the chaining, N levels deep of a set of stub implementations of interfaces that are necessary to satisfy your System Under Test in the course of doing the thing your test is actually supposed to be testing.

In general, you want short easy to read, easy to grok tests with minimal complexity and interaction of fixtures under the cover (no big hierarchy of base classes, or 6 different magic methods doing wacky teardown and calling base classes). Normally this aim will mean you should keep your DI toolery miles away from your unit tests.

An automocking container should, like a chainsaw, only be used where you're going to get a signnificant real return (many shorter, easier to understand tests) for you investment (another tool to understand before others can read you tests, more debugging, more surprises, more complexity that'll lead to brittle, unmaintainable tests).

Upvotes: 2

Related Questions