Autofixture: ConcurrentDictionary

Criado em 24 abr. 2020  ·  6Comentários  ·  Fonte: AutoFixture/AutoFixture

Oi,
Quando uso autofixture para gerar um Dictionary<T, U> recebo valores preenchidos nele por padrão, mas com um ConcurrentDictionary<T, U> não.

Isso é por design e devo usar um construtor de espécimes para alterar esse comportamento sozinho ou é um recurso ou bug ausente?

Comentários muito úteis

Olá,
Não posso dizer as razões por trás disso, mas olhando para o código-fonte, as coleções suportadas são codificadas.
Portanto, não é algo como "o tipo implementa o IDictionary", é "é tipo o Dicionário<,>". Portanto, ConcurrentDictionary não funciona.
Você não precisa criar seu próprio construtor de espécimes, você pode usar o que já está lá:

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

Todos 6 comentários

Se alguém mais se deparar com o mesmo problema, escrevi um construtor de espécimes para isso:

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

Olá,
Não posso dizer as razões por trás disso, mas olhando para o código-fonte, as coleções suportadas são codificadas.
Portanto, não é algo como "o tipo implementa o IDictionary", é "é tipo o Dicionário<,>". Portanto, ConcurrentDictionary não funciona.
Você não precisa criar seu próprio construtor de espécimes, você pode usar o que já está lá:

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

Quanto mais eu aprendo sobre o interior desta biblioteca, mais eu a amo

Interessante saber que está apenas em Dictionary<,> atualmente e obrigado pela maneira integrada de fazê-lo!

Acho que a única pergunta restante para alguém seria: esse seria um bom recurso para adicionar? Talvez não especificamente para ConcurrentDictionary<,> , mas para todas as implementações IDictionary<,> ?

Só que eu não espalhe informações erradas, não é só Dicionário<,>. Eu só queria salientar que a lista de tipos pode ser encontrada diretamente em Fixture.cs. Por exemplo, também é SortedDictionary<,>, mas como você já descobriu, não é ConcurrentDictionary<,>.
Por todos os meios, eu diria que uma implementação futura deve verificar a interface.

Na realidade, o que está codificado não é o suporte, mas o fato de que as interfaces são retransmitidas para algum tipo concreto. Como IDictionary e IReadOnlyDictionary são retransmitidos para o Dicionário e assim por diante.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

DeafLight picture DeafLight  ·  5Comentários

mjfreelancing picture mjfreelancing  ·  4Comentários

Accc99 picture Accc99  ·  4Comentários

zvirja picture zvirja  ·  4Comentários

tomasaschan picture tomasaschan  ·  3Comentários