Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 伪造合流的.NET卡夫卡消费者_C#_Unit Testing_Apache Kafka_Kafka Consumer Api_Fakeiteasy - Fatal编程技术网

C# 伪造合流的.NET卡夫卡消费者

C# 伪造合流的.NET卡夫卡消费者,c#,unit-testing,apache-kafka,kafka-consumer-api,fakeiteasy,C#,Unit Testing,Apache Kafka,Kafka Consumer Api,Fakeiteasy,环境:.NET 4.5。 假货:4.0.0 我试图创建一个Kafka consumer的假对象,下面是我使用的语法: var fakeconsumer = A.Fake<Consumer<Null, string>>((x => x.WithArgumentsForConstructor(() => new Consumer<Null, string>(A.Dummy<IEnumerable<KeyValuePair<string

环境:.NET 4.5。 假货:4.0.0

我试图创建一个Kafka consumer的假对象,下面是我使用的语法:

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>()))));
var fakeconsumer=A.Fake((x=>x.WithArgumentsForConstructor(()=>newconsumer(A.Dummy(),A.Dummy(),A.Dummy())));
卡夫卡客户端的代码如下:

如您所见,我使用构造函数所需的正确参数调用假调用。但是,我不断收到以下错误消息:“没有构造函数与传递给构造函数的参数匹配。”

非常感谢您的帮助

多谢各位

编辑:

在fakeitesy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.CreateProxyGeneratorResult(ProxyType、ProxyGenerationOptions、IEnumerable
1附加接口实现、IEnumerable
1参数构造函数、IFakeCallProcessorProvider fakeCallProcessorProvider)在C:\projects\fakeiteasy\src\fakeiteasy\Creation\CastleDynamicProxy\CastleDynamicProxyGenerator.cs中:第125行 在fakeitesy.Creation.CastleDynamicProxy.CastleDynamicProxyGenerator.GenerateProxy(ProxyType,ProxyGenerationOptions,IEnumerable
1 additionalInterfacesToImplement,IEnumerable
1 argumentsForConstructor,IfakeCallProcessor Provider FakeCallProcessor)在C:\projects\fakeiteasy\src\fakeiteasy\Creation\CastleDynamicProxy\CastleDynamicProxyGenerator.cs中:第86行 在C:\projects\FakeItEasy\src\FakeItEasy\Creation\FakeItEasy\FakeItEasy\Creation\FakeObjectCreator.cs第113行中的FakeItEasy.Creation.FakeObjectCreator.GenerateProxy(键入typeofake,IProxyOptions proxyOptions,IEnumerable
1 argumentsForConstructor)
在C:\projects\FakeItEasy\src\FakeItEasy\Creation\FakeObjectCreator.CreateFake(键入typeofake、IProxyOptions proxyOptions、DummyCreationSession会话、IDummyValueResolver解析器、Boolean throwOnFailure)中的C:\projects\FakeItEasy\Creation\FakeObjectCreator.cs:第36行
在C:\projects\FakeItEasy\src\FakeItEasy\Creation\defaultfakeanddummymymanager.CreateFake(键入typeofake,Action
1 optionsBuilder)中的FakeItEasy.Creation.defaultfakeanddummymymanager.CreateFake(键入typeofake,Action1 optionsBuilder):第41行 在C:\projects\FakeItEasy\src\FakeItEasy\A.cs中的FakeItEasy.A.Fake[T](Action`1 optionBuilder)处:第47行


我不是卡夫卡消费类的专家,但看起来您调用它的方式如下:

Consumer<Null, string>
消费者
但我在代码中能找到的唯一构造函数是:

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

public Consumer(
            IEnumerable<KeyValuePair<string, object>> config,
            IDeserializer<TKey> keyDeserializer,
            IDeserializer<TValue> valueDeserializer)
公共消费者(
IEnumerable配置)
公众消费者(
IEnumerable配置,
IDeserializer键反序列化器,
IDeserializer valueDeserializer)

所以没有对手。看起来您想使用第一个,因此您缺少了IEnumerable部分。

我相信我重现了您的问题。以下是我看到的全部例外:

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()
您可以看到FakeiTesy本身在调用
消费者
类的构造函数时遇到异常:

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(IEnumerable<KeyValuePair<string, object>> config,
         IDeserializer<TKey> keyDeserializer,
         IDeserializer<TValue> valueDeserializer)`
假货是伪造的


我注意到你交叉投递到。我将在这里做一个记录,以获得这个答案。

与原始问题没有100%的关联,但在我的库(Silverback:)中,我有一个Confluent.Kafka库的模拟内存实现,它允许进行一些复杂的集成测试。请参阅一些简单示例:

给你一个想法:

[Fact]
public async Task SampleTest()
{
    // Arrange
    var testingHelper = _factory.Server.Host.Services
        .GetRequiredService<IKafkaTestingHelper>();

    var producer = testingHelper.Broker
        .GetProducer(new KafkaProducerEndpoint("tst-topic"));

    // Act
    await producer.ProduceAsync(new TestMessage { Content = "abc" });

    await testingHelper.WaitUntilAllMessagesAreConsumedAsync();

    // Assert
    testingHelper.Spy.OutboundEnvelopes.Should().HaveCount(1);
    testingHelper.Spy.InboundEnvelopes.Should().HaveCount(1);
    testingHelper.Spy.InboundEnvelopes[0].Message.As<TestMessage>
        .Content.Should().Be("abc");
}
[事实]
公共异步任务SampleTest()
{
//安排
var testingHelper=\u factory.Server.Host.Services
.GetRequiredService();
var producer=testingHelper.Broker
.GetProducer(新卡夫卡普罗得伦德点(“tst主题”);
//表演
wait producer.ProduceAsync(新测试消息{Content=“abc”});
wait testingHelper.waitUntillallMessagesReconsumedAsync();
//断言
testingHelper.Spy.OutboundEnvelopes.Should().HaveCount(1);
testingHelper.Spy.InboundEnvelopes.Should().HaveCount(1);
testingHelper.Spy.InboundEnvelopes[0]。Message.As
.Content.Should()是(“abc”);
}
实现没有那么复杂,但它支持分区和再平衡机制的模拟。
请参阅实现:

以后,我建议阅读整个错误消息。这样可以完全避免提问。当问问题时,最好把整个错误都包括进去,因为它能真正帮助回答者。请参阅以了解更多信息。哦,顺便说一句,我看不出这是有文档记录的,但是Fakeitesy在制作赝品时会首先尝试使用无参数构造函数,如果没有,则会按照从大多数参数到最少参数的顺序使用构造函数。它将提供作为构造函数参数的假人。由于使用者没有无参数构造函数,所以您的原始代码相当于
var fakeconsumer=A.Fake()
。当然,对于首选构造函数可能总是有明确的理由的,即使您不需要指定参数,您也需要这样做(参见我的答案)。谢谢您发布解决方案。假电话现在很好用。我在异常处理程序中得到的调用堆栈是(如上面的编辑所示)。它不包括完整的卡夫卡消费者堆栈。我真的很感谢你的帮助。
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>()))));
[Fact]
public async Task SampleTest()
{
    // Arrange
    var testingHelper = _factory.Server.Host.Services
        .GetRequiredService<IKafkaTestingHelper>();

    var producer = testingHelper.Broker
        .GetProducer(new KafkaProducerEndpoint("tst-topic"));

    // Act
    await producer.ProduceAsync(new TestMessage { Content = "abc" });

    await testingHelper.WaitUntilAllMessagesAreConsumedAsync();

    // Assert
    testingHelper.Spy.OutboundEnvelopes.Should().HaveCount(1);
    testingHelper.Spy.InboundEnvelopes.Should().HaveCount(1);
    testingHelper.Spy.InboundEnvelopes[0].Message.As<TestMessage>
        .Content.Should().Be("abc");
}