I am using AutoMoqCustomization in my test conventions.
Consider the code below. Everything works great until I add a constructor to one of the concrete classes. When I do, I get "could not find a parameterless constructor". We know AutoFixture doesn't have an issue with the constructor because it delivered me the test object one
which proved to be assignable from IThings... no failure there. So it must be moq.
This makes some sense because I assume builder
was generated by moq and passed into the GetCommands
method. So I think I can see that control has been passed from AutoFixture to moq at that point.
That takes care of the why, but what should I do about it? Is there a way to instruct moq on how to deal with the ThingOne
or is there a way to instruct AutoFixture to ignore moq for IThingBuilders
and instead do something Fixtury?
public class TestClass
{
public interface IThingBuilders
{
T1 Build<T1>() where T1 : IThings;
}
public interface IThings
{
}
public class ThingOne : IThings
{
public ThingOne(string someparam)
{
}
}
public class ThingTwo : IThings
{
}
public class SomeClass
{
public List<IThings> GetCommands(IThingBuilders builder)
{
var newlist = new List<IThings>();
newlist.Add(builder.Build<ThingOne>());
newlist.Add(builder.Build<ThingTwo>());
return newlist;
}
}
[Theory, BasicConventions]
public void WhyCannotInstantiateProxyOfClass(ThingOne one, ThingTwo two, IThingBuilders builder, SomeClass sut)
{
Assert.IsAssignableFrom<IThings>(one);
Assert.IsAssignableFrom<IThings>(two);
var actual = sut.GetCommands(builder);
Assert.Equal(1, actual.OfType<ThingOne>().Count());
Assert.Equal(1, actual.OfType<ThingTwo>().Count());
}
}
As there's no extensibility point in Moq that enables AutoFixture to hook in and supply a value of ThingOne
, there's not a whole lot you can do.
However, you can use the SetReturnsDefault<T>
method of Moq. Modifying the above test would then be like this:
[Theory, BasicConventions]
public void WhyCannotInstantiateProxyOfClass(
ThingOne one, ThingTwo two, IThingBuilders builder, SomeClass sut)
{
Assert.IsAssignableFrom<IThings>(one);
Assert.IsAssignableFrom<IThings>(two);
Mock.Get(builder).SetReturnsDefault(one); // Add this to make the test pass
var actual = sut.GetCommands(builder);
Assert.Equal(1, actual.OfType<ThingOne>().Count());
Assert.Equal(1, actual.OfType<ThingTwo>().Count());
}
This is a bit easier than having to write a specific Setup
/Returns
pair, but not much. You could move that code to an AutoFixture Customization, but again, since this is a generic method on a a Mock instance, you'll explicitly need to call this for e.g. ThingOne in order to set the default for that return type. Not particularly flexible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With