如何指定伪造属性时要使用的类?

时间:2015-03-26 15:31:35

标签: fakeiteasy

我发现我经常伪造来自Entity Framework的IDbSet。我通常有这样的界面:

public interface IContext : IDisposable
{
    IDbSet<Cat> Cats { get; set; }
    IDbSet<Dogs> Dogs { get; set; }
}

我假装是这样的:

IContext context = A.Fake<IContext>();
context.Cats = new FakeDbSet<Cat>();
context.Dogs = new FakeDbSet<Dogs>();

最后两行代码变得很痛苦 FakeDbSet是一个自定义类,我们总是想要使用FakeItEasy假的。

有什么方法可以告诉FakeItEasy任何看到IDbSet的地方,使用FakeDbSet吗?

1 个答案:

答案 0 :(得分:3)

  

有什么方法可以告诉FakeItEasy它看到IDbSet的任何地方,使用FakeDbSet吗?

不是这样,不。有custom Dummies,其功能在即将发布的2.0版本中得到了极大的改进,但是当它们可以返回虚假类型时,属性不会返回虚拟对象(请参阅issue 156可能有太多关于此的信息)。否则,你就会全力以赴。

如果不这样做,最好的选择就是使用反射来查看属性的返回类型并相应地设置值。

您可以使用newly-expanded IFakeConfigurator powers in the 2.0 betas作为钩子来启用此行为,因此创建的每个假名都会检查其属性并添加所需的FakeDbSet

这样的事情:

public class PropertiesUseFakeDbSetFakeConfigurator : FakeConfigurator<IContext>
{
    protected override void ConfigureFake(IContext fakeObject)
    {
        var fakeObjectType = fakeObject.GetType();
        var properties = fakeObjectType.GetProperties(
            BindingFlags.Public |
            BindingFlags.Instance |
            BindingFlags.GetProperty |
            BindingFlags.SetProperty);

        foreach (var propertyInfo in properties)
        {
            var propertyType = propertyInfo.PropertyType;
            if (propertyType.IsGenericType &&
                propertyType.GetGenericTypeDefinition() == typeof (IDbSet<>))
            {
                var typeInTheSet = propertyType.GetGenericArguments()[0];
                var fakeDbSetType = typeof (FakeDbSet<>).MakeGenericType(typeInTheSet);
                var fakePropertyValue = Activator.CreateInstance(fakeDbSetType);

                propertyInfo.SetValue(fakeObject, fakePropertyValue, null);
            }
        }
    }
}

将通过:

[Test]
public void Properties_should_be_FakeDbSets()
{
    IContext context = A.Fake<IContext>();

    Assert.That(context.Cats, Is.InstanceOf<FakeDbSet<Cat>>());
    Assert.That(context.Dogs, Is.InstanceOf<FakeDbSet<Dog>>());
}

如果您的解决方案中有多个类IContext,则可能需要直接实施IFakeConfigurator,而不是使用FakeConfigurator<T>。它需要更多的工作,但提供了一种更复杂的方法来确定配置了哪些假货。 FakeConfigurator<IContext>只会配置伪造的IContext