2017-07-30 182 views
1

環境:.NET 4.5。 FakeItEasy:4.0.0僞裝Confluent .NET Kafka消費者

我想創建卡夫卡消費者的假冒對象,下面是我使用的語法:

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

卡夫卡客戶端的代碼是在這裏:https://github.com/confluentinc/confluent-kafka-dotnet/blob/master/src/Confluent.Kafka/Consumer.cs

由於你可以看到,我正在使用構造函數所需的正確參數調用Fake調用。但是我不斷收到以下錯誤消息:「沒有構造函數匹配構造函數傳遞的參數」。

任何幫助,非常感謝。

謝謝

編輯:

在FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.CreateProxyGeneratorResult(類型typeOfProxy,ProxyGenerationOptions選項,IEnumerable的1 additionalInterfacesToImplement, IEnumerable 1 argumentsForConstructor,IFakeCallProcessorProvider fakeCallProcessorProvider)在C:\項目\ fakeiteasy \ src \ FakeItEasy \ Creation \ CastleDynamicProxy \ CastleDynamicProxyGenerator.cs:第125行 位於FakeItEasy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.GenerateProxy(類型typeOfProxy,ProxyGenerationOptions選項,IEnumerable 1 additionalInterfacesToImplement, IEnumerable 1 argumentsForConstructor,IFakeCallProcessorProvider fakeCallProcessorProvider)在C:\項目\ fakeiteasy \ SRC \ FakeItEasy \創作\ CastleDynamicProxy \ CastleDynamicProxyGenerator.cs:線86 在FakeItEasy.Creation.FakeObjectCreator.GenerateProxy(類型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)在C:\ projects \ fakeiteasy \ src \ FakeItEasy \ Creation \ DefaultFakeAndDummyManager.cs中:第41行 在FakeItEasy.A.Fake [T](Action`1 optionsBuilder) CS:行47

+0

將來,我推薦閱讀整個錯誤信息。它可能避免需要提出一個問題。當提出問題時,包含整個錯誤是一個好主意,因爲它可以真正幫助答覆者。有關更多信息,請參閱https://stackoverflow.com/help/how-to-ask。 –

+0

呵呵,另外,我沒有記錄這些信息,但FakeItEasy在創建Fake時會首先嚐試使用無參數構造函數,如果沒有,將按大多數參數的順序使用構造函數。它將提供傻瓜作爲構造參數。由於Consumer沒有無參數構造函數,因此您的原始代碼等同於'var fakeconsumer = A.Fake >()'。當然,即使你不需要指定參數,你也需要做(請參閱我的答案),但總是有理由明確指出首選的構造函數。 –

回答

2

我相信我已經轉載了您的問題。下面是完整的例外,我看到:

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

你可以看到,FakeItEasy本身出現了一個錯誤,同時調用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. 

這是從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."); 
} 

看起來好像是

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

對其未滿足的輸入有一些要求。特別是,它似乎需要config包含一個帶有「group.id」鍵的元素。如果我將您的代碼更改爲

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

假貨已創建。

我注意到你交叉發佈到FakeItEasy Issue 1176。我會在那裏記下來回答這個問題。

+0

感謝您發佈解決方案。假電話現在工作正常。我在異常處理程序中獲得的調用堆棧是(如上面的編輯所示)。它不包括完整的卡夫卡消費者堆棧。我非常感謝你的幫助。 – Nandu

+0

我很高興你起來工作。 –

-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部分。