Autofixture: ConcurrentDictionary

作成日 2020年04月24日  ·  6コメント  ·  ソース: AutoFixture/AutoFixture

やあ、
自動フィクスチャを使用してDictionary<T, U>を生成すると、デフォルトで値が入力されますが、 ConcurrentDictionary<T, U>では入力されません。

これは仕様によるものであり、標本ビルダーを使用してその動作を自分で変更する必要がありますか、それとも欠落している機能またはバグですか?

最も参考になるコメント

こんにちは、
この背後にある理由はわかりませんが、ソースコードを見ると、サポートされているコレクションはハードコーディングされています。
つまり、「タイプはIDictionaryを実装しますか」ではなく、「タイプDictionary <、>」です。 したがって、ConcurrentDictionaryは機能しません。
独自の標本ビルダーを作成する必要はありません。すでに存在するものを使用できます。

      var fixture = new Fixture();

      var query = new ModestConstructorQuery();
      var methodInvoker = new MethodInvoker(query);
      var dictionaryFiller = new DictionaryFiller();
      var postProcessor = new Postprocessor(methodInvoker, dictionaryFiller);
      var exactTypeSpecification = new ExactTypeSpecification(typeof(ConcurrentDictionary<,>));
      var specimenBuilder = new FilteringSpecimenBuilder(postProcessor, exactTypeSpecification);

      fixture.Customizations.Add(specimenBuilder);

全てのコメント6件

他の誰かが同じ問題に遭遇した場合、私はこれのために標本ビルダーを書きました:

public class ConcurrentDictionaryGenerator : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        Type type = request as Type;
        if (type == null)
        {
            return new NoSpecimen();
        }

        Type[] typeArguments = type.GetTypeInfo().GetGenericArguments();
        if (typeArguments.Length != 2 || typeof(ConcurrentDictionary<,>).MakeGenericType(typeArguments) != type)
        {
            return new NoSpecimen();
        }

        Type nonConcurrentDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeArguments);
        IDictionary nonConcurrentDictionary = (IDictionary) context.Resolve(nonConcurrentDictionaryType);

        IDictionary concurrentDictionary = (IDictionary) Activator.CreateInstance(type);

        foreach (object key in nonConcurrentDictionary.Keys)
        {
            object value = nonConcurrentDictionary[key];
            concurrentDictionary.Add(key, value);
        }

        return concurrentDictionary;
    }
}

こんにちは、
この背後にある理由はわかりませんが、ソースコードを見ると、サポートされているコレクションはハードコーディングされています。
つまり、「タイプはIDictionaryを実装しますか」ではなく、「タイプDictionary <、>」です。 したがって、ConcurrentDictionaryは機能しません。
独自の標本ビルダーを作成する必要はありません。すでに存在するものを使用できます。

      var fixture = new Fixture();

      var query = new ModestConstructorQuery();
      var methodInvoker = new MethodInvoker(query);
      var dictionaryFiller = new DictionaryFiller();
      var postProcessor = new Postprocessor(methodInvoker, dictionaryFiller);
      var exactTypeSpecification = new ExactTypeSpecification(typeof(ConcurrentDictionary<,>));
      var specimenBuilder = new FilteringSpecimenBuilder(postProcessor, exactTypeSpecification);

      fixture.Customizations.Add(specimenBuilder);

このライブラリの内部について学ぶほど、私はそれを愛するようになります

それが現在Dictionary<,>だけにあることを知るのは興味深いことであり、それを行うための組み込みの方法に感謝します!

誰かに残っている唯一の質問は、次のようになると思います。これは追加するのに適した機能でしょうか。 おそらくConcurrentDictionary<,>の場合ではなく、すべてのIDictionary<,>の実装ですか?

私が間違った情報を広めないというだけで、それは辞書<、>だけではありません。 タイプのリストはFixture.csに直接あります。 たとえば、SortedDictionary <、>でもありますが、すでに理解しているように、ConcurrentDictionary <、>ではありません。
どうしても、将来の実装ではインターフェースをチェックする必要があると思います。

実際には、ハードコーディングされているのはサポートではなく、インターフェイスが特定のタイプに中継されるという事実です。 IDictionaryやIReadOnlyDictionaryのように、Dictionaryなどに中継されます。

このページは役に立ちましたか?
0 / 5 - 0 評価