Autofixture: ConcurrentDictionary

Créé le 24 avr. 2020  ·  6Commentaires  ·  Source: AutoFixture/AutoFixture

Salut,
Lorsque j'utilise l'autofixture pour générer un Dictionary<T, U> , j'obtiens des valeurs renseignées par défaut, mais avec un ConcurrentDictionary<T, U> je ne le fais pas.

Est-ce intentionnel et devrais-je utiliser un constructeur de spécimens pour modifier moi-même ce comportement, ou s'agit-il d'une fonctionnalité manquante ou d'un bogue ?

Commentaire le plus utile

Bonjour,
Je ne peux pas dire les raisons derrière cela, mais en regardant le code source, les collections prises en charge sont codées en dur.
Donc ce n'est pas quelque chose comme "le type implémente IDictionary", c'est "est le type Dictionary<,>". Par conséquent, ConcurrentDictionary ne fonctionne pas.
Vous n'avez pas besoin de créer votre propre constructeur de spécimens, vous pouvez utiliser ce qui existe déjà :

      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);

Tous les 6 commentaires

Si quelqu'un d'autre rencontre le même problème, j'ai écrit un constructeur de spécimens pour cela:

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;
    }
}

Bonjour,
Je ne peux pas dire les raisons derrière cela, mais en regardant le code source, les collections prises en charge sont codées en dur.
Donc ce n'est pas quelque chose comme "le type implémente IDictionary", c'est "est le type Dictionary<,>". Par conséquent, ConcurrentDictionary ne fonctionne pas.
Vous n'avez pas besoin de créer votre propre constructeur de spécimens, vous pouvez utiliser ce qui existe déjà :

      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);

Plus j'en apprends sur les caractéristiques internes de cette bibliothèque, plus je l'aime

Intéressant de savoir que c'est seulement sur Dictionary<,> actuellement et merci pour la manière intégrée de le faire !

Je suppose que la seule question restante pour quelqu'un serait alors : serait-ce une bonne fonctionnalité à ajouter ? Peut-être pas spécifiquement pour ConcurrentDictionary<,> , mais pour toutes les implémentations IDictionary<,> ?

Juste que je ne diffuse pas de fausses informations, ce n'est pas seulement Dictionary<,>. Je voulais juste préciser que la liste des types se trouve directement dans Fixture.cs. Par exemple, c'est aussi SortedDictionary<,>, mais comme vous l'avez déjà compris, ce n'est pas ConcurrentDictionary<,>.
Par tous les moyens, je dirais qu'une future implémentation devrait vérifier l'interface.

En réalité, ce qui est codé en dur, ce n'est pas le support, mais plutôt le fait que les interfaces sont relayées vers un type concret. Comme IDictionary et IReadOnlyDictionary sont relayés vers Dictionary, et ainsi de suite.

Cette page vous a été utile?
0 / 5 - 0 notes