Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoFixture and interfaces

Let's say I have interface:

public interface IFoo
{
    int Bar1 { get; set; }
    int Bar2 { get; set; }
}

If IFoo was class, I could write:

fixture.CreateAnonymous<IFoo>();

and the result will have numbers set for Bar1 and Bar2.

But how to do this with interface? I tried to use AutoMoqCustomization but this seems to be for properties with interface type and not interfaces itself.

I am looking for automated way like CreateAnonymous is for classes. Currenlty I am creating interface mock and setuping it's properties explicitly which is work I would like to save. I must missing something obvious.

like image 862
Pol Avatar asked Apr 18 '12 11:04

Pol


1 Answers

If you want to map an interface to a specific concrete class, you can certainly do that:

fixture.Register<IFoo>(() => fixture.CreateAnonymous<ConcreteFoo>());

(Or fixture.Register<IFoo>( fixture.CreateAnonymous<ConcreteFoo>) for short)

However, AutoMoq (as well as AutoRhinoMocks and AutoFakeItEasy) is also an option. With that, an attempt to create an instance of IFoo will return a Moq-created proxy which implements IFoo.

However, with Moq you aren't going to see the Bar1 and Bar2 populated. That's not only because AutoFixture doesn't invoke the setters, but because Moq doesn't (by default) implement the getters.

In order to make that work for Moq, one needs to invoke SetupAllProperties() on the Mock<T> itself. While possible, that's a little bit difficult to do in the current AutoMoq graph. There's already a work item for this, but if you read through the discussion you'll see that the issue is more complex than it would seem.

In any case, interfaces with properties is a bad idea for a number of other reasons too, so the best solution is to redesign the interface so that it doesn't have properties.

like image 99
Mark Seemann Avatar answered Oct 23 '22 07:10

Mark Seemann