Faking Confluent .NET Kafka consumers

Refresh

March 2019

Views

704 time

1

Environment: .NET 4.5. FakeItEasy : 4.0.0

I am trying to create a fake object of Kafka consumer, below is the syntax I use:

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

The code for Kafka client is here: https://github.com/confluentinc/confluent-kafka-dotnet/blob/master/src/Confluent.Kafka/Consumer.cs

As you can see, I am invoking the Fake call with correct parameters required for the constructor. However I keep getting the follow error message : "No constructor matches the passed arguments for constructor.".

Any help is greatly appreciated.

Thank you

Edit:

at FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.CreateProxyGeneratorResult(Type typeOfProxy, ProxyGenerationOptions options, IEnumerable1 additionalInterfacesToImplement, IEnumerable1 argumentsForConstructor, IFakeCallProcessorProvider fakeCallProcessorProvider) in C:\projects\fakeiteasy\src\FakeItEasy\Creation\CastleDynamicProxy\CastleDynamicProxyGenerator.cs:line 125 at FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.GenerateProxy(Type typeOfProxy, ProxyGenerationOptions options, IEnumerable1 additionalInterfacesToImplement, IEnumerable1 argumentsForConstructor, IFakeCallProcessorProvider fakeCallProcessorProvider) in C:\projects\fakeiteasy\src\FakeItEasy\Creation\CastleDynamicProxy\CastleDynamicProxyGenerator.cs:line 86 at FakeItEasy.Creation.FakeObjectCreator.GenerateProxy(Type typeOfFake, IProxyOptions proxyOptions, IEnumerable1 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, Action1 optionsBuilder) in C:\projects\fakeiteasy\src\FakeItEasy\Creation\DefaultFakeAndDummyManager.cs:line 41 at FakeItEasy.A.Fake[T](Action`1 optionsBuilder) in C:\projects\fakeiteasy\src\FakeItEasy\A.cs:line 47

2 answers

3

I believe I've reproduced your problem. Here's the full exception that I see:

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

You can see that FakeItEasy itself encountered an exception while calling the Consumer class's 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.

This was thrown from the 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.");
}

It seems that

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

Has some requirements on its inputs that aren't being met. In particular, it seems it needs config to contain one element with the key "group.id". If I change your code to

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

The fake is created.

I notice that you cross-posted to FakeItEasy Issue 1176. I'll make a note there to come here for this answer.

-1

Я не эксперт по классу потребителей для Кафки, но это выглядит как ваш вызываете его как:

Consumer<Null, string>

Но только Конструкторы я могу найти в коде:

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

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

Таким образом , нет не совпадают. Похоже , что вы хотите использовать первый, так что вам не хватает IEnumerable части.