4

我正在尝试测试一个使用存储库服务的服务类。我已经设置了我认为应该与我的存储库服务一起使用的自定义设置,而是返回默认的匿名结果。如果您查看下面的代码示例,当我调用 svc.GetFoos 方法时,我试图取回我在自定义类中注册的“Foo”对象,但我什么也没得到:

void Main()
{
    var fixture = new Fixture().Customize(
        new CompositeCustomization(
            new Customization(),
            new AutoMoqCustomization())); 

    var svc = fixture.CreateAnonymous<Bar>(); 

    Console.Write(svc.GetFoos().Count()); 
}

// Define other methods and classes here
public class Bar
{

    public IQueryable<Foo> GetFoos()
    {
        return _rep.Query<Foo>(); 
    }

    public Bar(IRepository rep) { _rep = rep;  }

    private IRepository _rep; 
}

public class Foo
{
    public string Name {get;set;}   
}

public class Customization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        var f = fixture
                .Build<Foo>()
                .With(x => x.Name, "FromCustomize")
                .CreateMany(2)
                .AsQueryable();
        fixture.Register<IQueryable<Foo>>(() => f); 
    }
}

public interface IRepository
{
    IQueryable<T> Query<T>(); 
}

如果我在夹具实例化之后将以下代码添加到 Main 方法中,它会按我想要的方式工作,但是我手动设置了我的模拟,我不确定 AutoFixture AutoMoq 给我带来了什么:

var mock = fixture.Freeze<Mock<IRepository>>(); 
mock
    .Setup(x => x.Query<Foo>())
    .Returns(fixture.CreateAnonymous<IQueryable<Foo>>); 

谢谢。

4

2 回答 2

5

AutoFixture.AutoMoq 用作自动模拟容器Mock<T>它会通过将实例注入到 said 的任何消费者中来自动组成对象图T

它不能Mock<T>为您配置实例——毕竟,它怎么可能呢?只有您(测试编写者)知道适当的交互应该是什么。

Setup因此,您提供的代码(包括对and的调用Returns)是正确的,尽管您可能会考虑Customization该类是否过度杀伤。

如果您需要自动化大量重复的起订量设置,您应该考虑

  • 界面设计和消费模式是否合适
  • 如果Fake不是比动态模拟更好的选择
于 2012-10-19T00:51:02.313 回答
0

我最近遇到了一个类似的话题。我无法对自动创建的IQueryable<T>.

“System.Object”类型的表达式不能用于“Boolean Any”方法的“System.Linq.IQueryable`1[System.String]”类型的参数...

我通过创建一个特殊的样本构建器来解决这个问题,它总是创建一个数组,然后返回它AsQueryable。最后我没有使用代码,但它有效。

很明显很粗糙,只是尝试一下......

void Main()
{
    Fixture fixture = new Fixture();

    fixture.Customize(new AutoMoqCustomization { ConfigureMembers = true, Relay = new QueryableBuilder() });

    // Possible ways to "override" the AutoMoqBehavior
//  fixture.Inject<string>("hallO");
//  fixture.Inject(new[] { "asd" });
//  fixture.Inject(new[] { "asds" }.AsQueryable());

    var queryable = fixture.Create<Foo>();
    queryable.Bar();

    fixture.Create<IQueryable<string>>().Any(x => x.Equals("asd"));
}

public class QueryableBuilder : ISpecimenBuilder
{
    MockRelay _Base = new MockRelay();

    public object Create(object request, ISpecimenContext context)
    {
        var t = request as Type;
        if (t == null ||
            !t.IsGenericType ||
            t.GetGenericTypeDefinition() != typeof(IQueryable<>))
            return _Base.Create(request, context);

        var queryableTypeName = typeof(IQueryable<>).Name;
        if (t.Name != queryableTypeName)
            return _Base.Create(request, context);

        var entityType = t.GetGenericArguments().Single();

        var tt = entityType.MakeArrayType();
        dynamic blbb = context.Resolve(tt);
        return ((IEnumerable)blbb).AsQueryable();
    }
}

public interface IHaveQueryable {
    IQueryable<string> Queryable {get;}
}

public class Foo {

    readonly IHaveQueryable _Queryable;

    public Foo(IHaveQueryable queryable){
        _Queryable = queryable;
    }

    public bool Bar(){
        return _Queryable.Queryable.Any(x => x.Equals("bar"));
    }
}
于 2020-02-18T16:53:17.787 回答