英文:
Moq Raise event of Func<T1, Task>
问题
我有一个第三方类MqttClient
,它内部有一个事件(Func<T1, Task>
)。我想在MyClient
类内监听此事件,并在事件被触发时更新我的类内的IsConnected
属性。为了进行测试,我已经模拟了IMqttClient
接口,并希望引发该事件,以便在发生时测试我的属性是否得到更新。然而,当我尝试这样做时,出现了关于参数计数不匹配的错误。
以下是我尝试的测试:
[Fact]
public void Connect_IsConnectedSetToTrue()
{
MqttClientConnectedEventArgs eventArgs = new(new MqttClientConnectResult());
_mockMqttNetClient.Raise(x => x.ConnectedAsync += null);
_mqttClient.Connect();
Assert.True(_mqttClient.IsConnected);
}
[Fact]
public void Connect_IsConnectedSetToTrue()
{
MqttClientConnectedEventArgs eventArgs = new(new MqttClientConnectResult());
_mockMqttNetClient.Raise(x => x.ConnectedAsync += null, eventArgs);
_mqttClient.Connect();
Assert.True(_mqttClient.IsConnected);
}
[Fact]
public void Connect_IsConnectedSetToTrue()
{
MqttClientConnectedEventArgs eventArgs = new(new MqttClientConnectResult());
_mockMqttNetClient.Raise(x => x.ConnectedAsync += null, this, eventArgs);
_mqttClient.Connect();
Assert.True(_mqttClient.IsConnected);
}
MyClient
类如下:
public class MyClient
{
private readonly IMqttClient _client;
public bool IsConnected { get; private set; } = false;
public MQTTClient(IMQTTNetClientFactory mqttNetFactory)
{
_client = mqttNetFactory.Create();
_client.ConnectedAsync += Client_ConnectedAsync;
}
public async Task Connect()
{
MqttClientOptions options = new MqttClientOptionsBuilder()
.WithTcpServer(_url, _port)
.WithCredentials(_username, _password)
.WithProtocolVersion(MqttProtocolVersion.V500)
.Build();
await _client.ConnectAsync(options);
}
private Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg)
{
_logger.LogInformation("Client connected to the MQTT broker.");
IsConnected = true;
return Task.FromResult(0);
}
}
MqttClient
类内的事件如下:
public interface IMqttClient : IDisposable
{
event Func<MqttClientConnectedEventArgs, Task> ConnectedAsync;
}
希望这些信息对你有所帮助,如果你需要更多的解释或帮助,请随时提出。
英文:
I have a third-party class MqttClient
which has an event inside it (Func<T1, Task>
). I want to listen for this event inside the MyClient
class and when it gets invoked, I update the property IsConnected
inside my class. For my tests, I have mocked the IMqttClient
interface, and I want to raise that event so that I can test that my property gets updated when it happens. However, when I try to do this I get an error about parameter count mismatches. I've found a lot of examples about using EventHandler<T>
but since this class is outside of my control, I need it to work with a Func
.
> System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'
Here are the tests I've tried:
[Fact]
public void Connect_IsConnectedSetToTrue()
{
MqttClientConnectedEventArgs eventArgs = new(new MqttClientConnectResult());
_mockMqttNetClient.Raise(x => x.ConnectedAsync += null);
_mqttClient.Connect();
Assert.True(_mqttClient.IsConnected);
}
[Fact]
public void Connect_IsConnectedSetToTrue()
{
MqttClientConnectedEventArgs eventArgs = new(new MqttClientConnectResult());
_mockMqttNetClient.Raise(x => x.ConnectedAsync += null, eventArgs);
_mqttClient.Connect();
Assert.True(_mqttClient.IsConnected);
}
[Fact]
public void Connect_IsConnectedSetToTrue()
{
MqttClientConnectedEventArgs eventArgs = new(new MqttClientConnectResult());
_mockMqttNetClient.Raise(x => x.ConnectedAsync += null, this, eventArgs);
_mqttClient.Connect();
Assert.True(_mqttClient.IsConnected);
}
The MyClient
class:
public class MyClient
{
private readonly IMqttClient _client;
public bool IsConnected { get; private set; } = false;
public MQTTClient(IMQTTNetClientFactory mqttNetFactory)
{
_client = mqttNetFactory.Create();
_client.ConnectedAsync += Client_ConnectedAsync;
}
public async Task Connect()
{
MqttClientOptions options = new MqttClientOptionsBuilder()
.WithTcpServer(_url, _port)
.WithCredentials(_username, _password)
.WithProtocolVersion(MqttProtocolVersion.V500)
.Build();
await _client.ConnectAsync(options);
}
private Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg)
{
_logger.LogInformation("Client connected to the MQTT broker.");
IsConnected = true;
return Task.FromResult(0);
}
}
This is what the event looks like inside the MqttClient
class.
public interface IMqttClient : IDisposable
{
event Func<MqttClientConnectedEventArgs, Task> ConnectedAsync;
}
Thanks,
Adam
答案1
得分: 2
按照 @Ralf 所说:
> 你使用的 raise 重载期望它是一个事件处理程序(发送方+参数的东西),但只提供了一个参数类,并将发送方搞进了调用中
以这种方式解决了我的问题。
_mockMqttNetClient.Raise(x => x.DisconnectedAsync += null, new object[] { eventArgs });
英文:
As @Ralf said
> The raise overload you use expects that it is an Eventhandler(the sender+args thingy) when only given an args class and fiddles a sender into the call
Doing it this way solved my issue.
_mockMqttNetClient.Raise(x => x.DisconnectedAsync += null, new object[] { eventArgs });
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论