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メソッドに追加すると、希望どおりに機能しますが、手動でモックを設定しているため、AutoFixtureAutoMoqが何を取得しているかわかりません。

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>上記のコンシューマーにインスタンスを挿入することにより、オブジェクトグラフを自動的に作成しますT

インスタンスを構成することはできませMock<T>ん-結局のところ、どうすればよいでしょうか?適切な相互作用がどうあるべきかを知っているのはあなた(テストライター)だけです。

したがって、とへの呼び出しを含め、提示するコードSetupは正しいですが、クラスがやり過ぎReturnsかどうかを検討することもできます。Customization

Moqの繰り返しのセットアップを自動化する必要がある場合は、次のことを検討する必要があります。

  • インターフェイスデザインと消費パターンが適切かどうか
  • 偽物が動的モックよりも優れたオプションではない場合
于 2012-10-19T00:51:02.313 に答える
0

私は最近、同様のトピックに出くわしました。自動的に作成したのクエリを実行できませんでしたIQueryable<T>

タイプ'System.Object'の式は、メソッド'BooleanAny..のタイプ'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 に答える