1

Environnement: .NET 4.5. FakeItEasy: 4.0.0Faking Confluent .NET Consommateurs Kafka

Je suis en train de créer un objet faux de consommateurs Kafka, ci-dessous est la syntaxe que j'utilise:

var fakeconsumer = A.Fake<Consumer<Null, string>>((x => x.WithArgumentsForConstructor(() => new Consumer<Null, string>(A.Dummy<IEnumerable<KeyValuePair<string, object>>>(), A.Dummy<IDeserializer<Null>>(), A.Dummy<StringDeserializer>())))); 

Le code pour le client Kafka est ici: https://github.com/confluentinc/confluent-kafka-dotnet/blob/master/src/Confluent.Kafka/Consumer.cs

Comme vous pouvez voir, j'appelle l'appel Faux avec les paramètres corrects requis pour le constructeur. Cependant, je reçois toujours le message d'erreur suivant: "Aucun constructeur ne correspond aux arguments passés pour le constructeur.".

Toute aide est grandement appréciée.

Merci

Edit:

à FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.CreateProxyGeneratorResult (Type typeOfProxy, options ProxyGenerationOptions, IEnumerable 1 additionalInterfacesToImplement, IEnumerable 1 argumentsForConstructor, IFakeCallProcessorProvider fakeCallProcessorProvider) dans C: \ projects \ fakeiteasy \ src \ FakeItEasy \ Creation \ CastleDynamicProxy \ CastleDynamicProxyGenerator.cs: ligne 125 à FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.GenerateProxy (Type typeOfProxy, options ProxyGenerationOptions, IEnumerable 1 additionalInterfacesToImplement, IEnumerable 1 argumentsForConstructor, IFakeCallProcessorProvider fakeCallProcessorProvider) dans C: \ projets \ fakeiteasy \ src \ FakeItEasy \ Création \ CastleDynamicProxy \ CastleDynamicProxyGenerator.cs: ligne 86 à FakeItEasy.Creation.FakeObjectCreator.GenerateProxy (Type typeOfFake, IProxyOptions proxyOptions, IEnumerable 1 argumentsForConstructor) in C:\projects\fakeiteasy\src\FakeItEasy\Creation\FakeObjectCreator.cs:line 113 at FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, IProxyOptions proxyOptions, DummyCreationSession session, IDummyValueResolver resolver, Boolean throwOnFailure) in C:\projects\fakeiteasy\src\FakeItEasy\Creation\FakeObjectCreator.cs:line 36 at FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, Action 1 optionsBuilder) dans C: \ projects \ fakeiteasy \ src \ FakeItEasy \ Création \ DefaultFakeAndDummyManager.cs: ligne 41 à FakeItEasy.A.Fake [T] (Action`1 optionsBuilder) dans C: \ projects \ fakeiteasy \ src \ FakeItEasy \ A. cs: ligne 47

+0

À l'avenir, je recommande de lire tout le message d'erreur. Cela peut éviter de devoir poser une question. Et lorsque vous posez une question, c'est une bonne idée d'inclure toute l'erreur, car cela peut vraiment aider les répondeurs. Voir https://stackoverflow.com/help/how-to-ask pour plus d'informations. –

+0

Oh, et un aparté, ce n'est pas documenté que je peux dire, mais FakeItEasy essaiera d'abord d'utiliser le constructeur sans paramètre en faisant un Fake, et s'il n'y en a aucun, utilisera les constructeurs dans l'ordre de la plupart des paramètres. Et cela fournira des Dummies en tant qu'arguments constructeurs. Puisque Consumer n'a pas de constructeur sans paramètre, votre code original est équivalent à 'var fakeconsumer = A.Fake >()'. Bien sûr, il peut toujours y avoir des raisons d'être explicite sur le constructeur préféré, même si vous n'avez pas besoin de spécifier des arguments, ce que vous devrez faire (voir ma réponse). –

Répondre

2

Je crois que j'ai reproduit votre problème.Voici la pleine exception que je vois:

FakeItEasy.Core.FakeCreationException : 
    Failed to create fake of type Confluent.Kafka.Consumer`2[Confluent.Kafka.Null,System.String] with the specified arguments for the constructor: 
    No constructor matches the passed arguments for constructor. 
    An exception of type System.ArgumentException was caught during this call. Its message was: 
    'group.id' configuration parameter is required and was not specified. 
     at Confluent.Kafka.Consumer..ctor(IEnumerable`1 config) 
     at Confluent.Kafka.Consumer`2..ctor(IEnumerable`1 config, IDeserializer`1 keyDeserializer, IDeserializer`1 valueDeserializer) 
     at Castle.Proxies.Consumer`2Proxy..ctor(IInterceptor[] , IEnumerable`1 , IDeserializer`1 , IDeserializer`1) 
    at FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithArgumentsForConstructor(Type typeOfFake, String reasonForFailure) 
    at FakeItEasy.Creation.FakeObjectCreator.AssertThatProxyWasGeneratedWhenArgumentsForConstructorAreSpecified(Type typeOfFake, ProxyGeneratorResult result, IProxyOptions proxyOptions) 
    at FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, IProxyOptions proxyOptions, DummyCreationSession session, IDummyValueResolver resolver, Boolean throwOnFailure) 
    at FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, Action`1 optionsBuilder) 
    at FakeItEasy.A.Fake[T](Action`1 optionsBuilder) 
    Kafka.cs(14,0): at FakeItEasyQuestions2015.Kafka.MakeConsumer() 

Vous pouvez voir que FakeItEasy se rencontre une exception tout en appelant le constructeur de la classe Consumer:

An exception of type System.ArgumentException was caught during this call. Its message was: 
    'group.id' configuration parameter is required and was not specified. 

Cela a été jeté du Consumer constructor on line 756:

if (config.FirstOrDefault(prop => string.Equals(prop.Key, "group.id", StringComparison.Ordinal)).Value == null) 
{ 
    throw new ArgumentException("'group.id' configuration parameter is required and was not specified."); 
} 

Il semble que

Consumer(IEnumerable<KeyValuePair<string, object>> config, 
     IDeserializer<TKey> keyDeserializer, 
     IDeserializer<TValue> valueDeserializer)` 

A certaines exigences sur ses entrées qui ne sont pas respectées. En particulier, il semble qu'il faut config pour contenir un élément avec la clé "group.id". Si je change votre code en

var fakeconsumer = A.Fake<Consumer<Null, string>>(
    (x => x.WithArgumentsForConstructor(
     () => new Consumer<Null, string>(new [] { new KeyValuePair<string, object>("group.id", "hippo")}, 
     A.Dummy<IDeserializer<Null>>(), 
     A.Dummy<StringDeserializer>())))); 

Le faux est créé.

Je remarque que vous avez coché la case FakeItEasy Issue 1176. Je ferai une note pour venir ici pour cette réponse.

+0

Merci d'avoir posté la solution. Le faux appel fonctionne bien maintenant. La pile d'appels que j'ai reçue dans le gestionnaire d'exceptions était (comme indiqué dans l'édition ci-dessus). Il n'incluait pas la pile complète du kafka. J'apprécie vraiment votre aide. – Nandu

+0

Je suis content que vous soyez en pleine forme. –

-1

Je ne suis pas expert sur la classe des consommateurs pour Kafka, mais il semble que votre invoquez comme il:

Consumer<Null, string> 

Mais les seuls constructeurs que je peux trouver dans le code sont:

public Consumer(
     IEnumerable<KeyValuePair<string, object>> config) 

public Consumer(
      IEnumerable<KeyValuePair<string, object>> config, 
      IDeserializer<TKey> keyDeserializer, 
      IDeserializer<TValue> valueDeserializer) 

donc il n'y a pas de match . Il semble que vous vouliez utiliser le premier, il vous manque donc la partie IEnumerable.