AutoFixture as an Automocking container vs Automocking differences?
Asked Answered
M

1

12

I started to use moq but from my understanding I always have to mock up all the methods that could be called even if I really do not care about them.

Sometimes it takes so long to mockup stuff you forget what you want to do. So I been looking at auto mocking but I am not sure what one I should use.

AutoFixture as an auto-mocking container

Automocking

I don't get how to use the first one at all. I sort of get the second one but never really tried it.

I am not sure if one is better than the other. The only thing I know is I am using AutoFixtures already what is a dependency of the first one.

So maybe in the long run it makes sense to go with the first one but like I said I can't find any basic tutorials on how to use it.

Edit

I am trying to follow "Nikos Baxevanis" examples but I am running into errors.

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


var fixture = new Fixture().Customize(new AutoMoqCustomization());
        var fooMock = fixture.Freeze<Mock<IFoo>>();
       // fooMock.Setup(x => x.GetAccounts(It.IsAny<IUnitOfWork>()));
        var sut = fixture.CreateAnonymous<AdminService>();

        sut.Apply();
        fooMock.VerifyAll();

I think it is because of my petapoco unitOfWork property

PetaPoco.Database Db { get; }

Not sure if I got to mock this up somehow or what.

Mohenjodaro answered 12/10, 2012 at 23:0 Comment(2)
About the exception that you get, there is nothing wrong with the way you use AutoFixture and Auto-Mocking. I would be happy to help further if you can include in your question the source code for all the types used by the test.Lishalishe
Ya I been walking through the code and the problem is in my service layer method(the method I am trying to unit test). A call is made. Eventhough I have a unit of work that is an interface the property Db is not a interface and that is causing it to crash. I have to mock it out but the petapoco does not have an interface. So I to wrap it I guessMohenjodaro
L
27

While I have never used moq-contrib Automocking, I could probably provide some information on using AutoFixture as an auto-mocking container.

Currently there is support for Moq, Rhino Mocks, FakeItEasy, and NSubstitute. Just install the appropriate extension AutoMoq, AutoRhinoMocks, AutoFakeItEasy, and AutoNSubstitute.

Once you have installed one of the extensions for Auto Mocking the extra call is:

var fixture = new Fixture()
    .Customize(new AutoMoqCustomization());

(or if you are using Rhino Mocks)

var fixture = new Fixture()
     .Customize(new AutoRhinoMockCustomization());

(or if you are using FakeItEasy)

var fixture = new Fixture()
     .Customize(new AutoFakeItEasyCustomization());

(or if you are using NSubstitute)

var fixture = new Fixture()
     .Customize(new AutoNSubstituteCustomization());

Example 1

public class MyController : IController
{
    public MyController(IFoo foo)
    {
    }
}

public interface IFoo
{
}

Here is how to use AutoFixture to create instances of MyController class:

var fixture = new Fixture()
    .Customize(new AutoMoqCustomization());

var sut = fixture.CreateAnonymous<MyController>();

Now, if you inspect the sut variable you will see the the IFoo is a mocked instance (having a type name similar to Castle.Proxies.IFooProxy).

Example 2

This examples extends the previous one.

You can instruct AutoFixture to use your own, pre-configured, mocked instance:

var fooMock = fixture.Freeze<Mock<IFoo>>();
// At this point you may setup expectation(s) on the fooMock.

var sut = fixture.CreateAnonymous<MyController>();
// This instance now uses the already created fooMock.
// Verify any expectation(s).

That's basically it - but it can go further!

Below are the previous examples using AutoFixture decleratively with the xUnit.net extension.

Example 1

[Theory, AutoMoqData]
public void TestMethod(MyController sut)
{
    // Start using the sut instance directly.
}

Example 2

[Theory, AutoMoqData]
public void TestMethod([Frozen]Mock<IFoo> fooMock, MyController sut)
{
   // At this point you may setup expectation(s) on the fooMock.
   // The sut instance now uses the already created fooMock.
   // Verify any expectation(s).
}

You may find more information on this blog post which contains links to everything related around AutoFixture, xUnit.net, and Auto Mocking.

Hope that helps.

Lishalishe answered 13/10, 2012 at 7:42 Comment(10)
What is Freeze? I don't get it. Your 2nd example is showing how to mockup everything but if you want to start passing in your own stuff then that is what you do?Mohenjodaro
You may Freeze an instance of a type so that when AutoFixture needs to create an instance of the same type it will reuse the already created one. You may find more information about this feature here.Lishalishe
Keep in mind that Freeze is needed only if you need to set an expectation to a mocked instance which is a dependency of the requested type. (Of course, you may have to freeze more than one type instances depending on the scenario.)Lishalishe
Hmm ok, Got to play around with it but my undestanding of is correct right? That these will make a fake mockup of all methods(that have an interfaces) right? Then the methods you care about can then go further and setup them up with moq setup function? I also don't 100% get what is going on here var fooMock = fixture.Freeze<Mock<IFoo>>(); Why did you go out of your way to mock IFoo where in the 1st example you did not.Mohenjodaro
On Example 1 we don't really care to setup an expectation on the IFoo mock. We just go ahead and ask AutoFixture to create an instance of the MyController type. This will automatically inject a mocked instance of IFoo type. On Example 2, we do want to setup and expectation so we manually create a mocked instance and we Freeze it - telling AutoFixture to reuse the already created instance when requesting the MyController type. (If we don't do that, the expectation would fail since the MyController is going to use another instance - not the one that we setup the expectation.)Lishalishe
Would it be bad to just create the fixture in the constructor and then use it through all the tests?Mohenjodaro
@ Nikos Baxevanis - Been trying to get your code examples to work in my project but I keep getting an error. See my OP.Mohenjodaro
In this particular scenario, I would strongly suggest to let AutoFixture handle the object creation including any of the dependencies. Your unit tests are more robust that way - e.g. if for some reason you modify the constructor(s) there are less chances for compile time erros.Lishalishe
I been playing around with your examples and I wanted to confirm that order seems to matter? I tried making the controller object first then the IFooMock and my unit tests failed(since I used moq verify and said the method should only be called once). I am thinking it first made the automock then it made the mock that I told it to make thus calling each method twice?Mohenjodaro
Yes, that is expected because first you requested the MyController type (so AutoFixture supplied an auto-mocked instance for the IFoo dependency) and after you created a new mock of IFoo (which is a different instance of the one that was passed in the MyController). When you need to set an expectation on a mock Freeze it before you request a type that depends on the mocked object. That way, AutoFixture will reuse the already created mock and the expectation will succeed.Lishalishe

© 2022 - 2024 — McMap. All rights reserved.