9

リポジトリ実装の単体テストを作成しようとしています。リポジトリは RavenDB をデータベースとして使用します。単体テストのために、RavenDB の部分をモックしたいと思います。モック (偽物) を作成するために、FakeItEasy を使用しています。RavenDB API はインターフェイスを介してアクセスされるため、モッキング/フェイクに問題はないと考えました。

ただし、特定のモックをインスタンス化しようとすると問題が発生します。単体テスト コードの関連部分は次のようになります。

[Fact]
public void Test() {
    UserDocument doc = ...;
    IQueryable<UserDocument> where = A.Fake<IQueryable<UserDocument>>();
    A.CallTo(() => where.First()).Returns(doc);
    IRavenQueryable<UserDocument> query = A.Fake<IRavenQueryable<UserDocument>>();
    IDocumentSession session = A.Fake<IDocumentSession>();
    A.CallTo(() => session.Query<UserDocument>()).Returns(query);
    IDocumentStore store = A.Fake<IDocumentStore>();
    A.CallTo(() => store.OpenSession()).Returns(session);
    .
    .
    .
}

IRavenQueryable 偽物をインスタンス化すると、例外が発生します。これは、Xunit.net ランナーからのログです。

UnitTest.Test : FakeItEasy.Core.FakeCreationException : 
  Failed to create fake of type "System.Linq.IQueryable`1[UserDocument]".

  Below is a list of reasons for failure per attempted constructor:
    No constructor arguments failed:
      No default constructor was found on the type System.Linq.IQueryable`1[UserDocument].


Stack Trace:
   vid FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithResolvedConstructors(Type typeOfFake, String reasonForFailureOfUnspecifiedConstructor, IEnumerable`1 resolvedConstructors)
   vid FakeItEasy.Creation.FakeObjectCreator.TryCreateFakeWithDummyArgumentsForConstructor(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, String failReasonForDefaultConstructor, Boolean throwOnFailure)
   vid FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, Boolean throwOnFailure)
   vid FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, FakeOptions options)
   vid FakeItEasy.Creation.DefaultFakeCreatorFacade.CreateFake[T](Action`1 options)

私が偽造しようとしているのはインターフェースであるため、「デフォルトのコンストラクターが見つかりません」は意味がありません。何が問題なのか誰か提案がありますか?

4

4 に答える 4

11

例外メッセージが意味をなさないという点で正しいです。これはバグです。バグを再現し、ここで問題を報告する VS ソリューションを提供していただければ幸いです: https://github.com/patrik-hagne/FakeItEasy/

バグは、間違った例外メッセージが使用されることにありますが、偽の作成がうまくいかない何かが間違っているに違いありません。「UserDocument」タイプは公開されていますか? それが内部であり、InternalsVisibleToAttribute を使用してテスト プロジェクトへのアクセスを許可している場合は、プロキシ生成ライブラリへのアクセスも許可する必要があります: https://fakeiteasy.readthedocs.io/en/stable/how-to -fake-internal-types/#how-to-fake-internal-friend-in-vb-types .

于 2011-10-02T16:36:05.790 に答える
3

古い投稿であることは知っていますが、同じ問題に遭遇しました。問題であることがわかったのは、偽造しようとしていたインターフェイスに宣言されたメソッドの 1 つの戻り値の型でした。このメソッドは特定のクラスのオブジェクトを返していましたが、このクラスには FakeItEasy が動作するデフォルトのコンストラクターがありませんでした。他の誰かがこのエラーを受け取った場合は、インターフェイスが返すオブジェクトを確認し、対応するクラスにデフォルトのコンストラクターがあるかどうかを確認してください。

于 2012-10-25T07:45:19.473 に答える
2

IRavenQueryable<T>インターフェイスにはwhere T : new() 型制約がありますか?

その場合UserDocument、パラメータのない ctor が提供されない場合、これが問題の原因である可能性があります。

于 2011-09-26T18:19:27.930 に答える
2

私はこれに遭遇しましたが、私の問題は内部型に関するものではありませんでした。私の問題は、単体テスト プロジェクトの bin フォルダーにない型を含むアセンブリにありました。

偽造する必要がある型を解決できない場合、FakeItEasy はこのエラーをスローするようです。(これは、別のアセンブリの内部型が同じエラーを引き起こす理由を理解しています。)

そのため、Project Bar によって参照される Project Foo がありました。Project Bar には、Project Foo のパブリック型を参照するパブリック インターフェイスがありました。Project Bar.Tests には Project Bar への参照がありますが、Project Foo への参照はありません。Bar.Tests をビルドすると、Bar.dll は bin フォルダーに配置されますが、Foo.dll は配置されません。FakeItEasy が私のインターフェイスを偽造しようとすると、Foo.dll にある型を解決できません。

Bar.Tests プロジェクトに Project Foo への参照を追加すると、Foo.dll が確実に FakeItEasy に存在し、このエラーが消えました。

そう...

あなたの場合、RavenDB アセンブリ (含まれていると思われますUserDocument) が実際のプロジェクトによってのみ参照され、単体テストのビルド出力にコピーされていない可能性があります。

于 2011-10-12T21:37:12.300 に答える