处理AutoFixture和Moq之间的样本创建不一致

时间:2013-08-28 20:22:10

标签: moq autofixture

我在测试约定中使用AutoMoqCustomization。

请考虑以下代码。在我将一个构造函数添加到其中一个具体类之前,一切都很有效。当我这样做时,我得到“找不到无参数构造函数”。我们知道AutoFixture没有构造函数的问题,因为它向我提供了测试对象one,它被证明可以从IThings分配......没有失败。所以一定是moq。

这是有道理的,因为我假设builder是由moq生成的,并传递给GetCommands方法。所以我想我可以看到控件已经从AutoFixture传递到moq了。

这可以解决原因,但我该怎么做呢?有没有办法指示moq如何处理ThingOne或有没有办法指示AutoFixture忽略IThingBuilders的moq而是做一些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());
    }
}

1 个答案:

答案 0 :(得分:3)

由于Moq中没有延伸点可以使AutoFixture挂钩并提供ThingOne的值,因此您无法做很多事情。

但是,可以使用Moq的SetReturnsDefault<T>方法。修改上述测试将是这样的:

[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());
}

这比编写特定的Setup / Returns对要容易一些,但并不多。您可以将该代码移动到AutoFixture Customization,但同样,因为这是Mock实例上的通用方法,您明确需要将其调用为例如ThingOne以设置该返回类型的默认值。不是特别灵活。