gpt4 book ai didi

c# - 有什么理由更喜欢模拟接口(interface)而不是具有可覆盖成员的类?

转载 作者:行者123 更新时间:2023-11-30 12:09:36 25 4
gpt4 key购买 nike

我有一个用于交换消息的外部库。在这个库中,我有一个名为 Channel 的对象。

这是反编译dll后的结果:

public class Channel 
{
public State CurrentState { get { /*Only for code compiling, the value depend on the TCP Connection state.*/return State.ERROR; } }
public bool Send(string message)
{
//Some stuff with TCP connection.
return true;
}

public enum State
{
DISCONNECTED,
CONNECTED,
ERROR
}
}

现在在我的代码中,我在类中使用此 Channel 来发送消息,该类如下所示:

public class ClientConnection
{
private Channel MyChannel;

public ClientConnection(Channel channel)
{
MyChannel = channel;
}

public bool Send(string message)
{
bool result = false;
if(MyChannel.CurrentState == Channel.State.CONNECTED)
{
result = MyChannel.Send(message);
}
return result;
}
}

所以我的目标是对其进行测试,验证是否调用了方法 send,并检查参数是否与我的输入匹配。这里的问题是没有接口(interface)和方法不是虚拟的,所以不能直接模拟。

我做了什么我创建了一个具有可覆盖属性和方法的包装器,如下所示:

public class ChannelWrapper
{
private readonly Channel channel;
public ChannelWrapper(Channel channel)
{
this.channel = channel;
}
public virtual Channel.State CurrentState { get { return channel.CurrentState; } }
public virtual bool Send(string message)
{
return channel.Send(message);
}
}

并在 ClientConnection 的构造函数和属性中将类型 Channel 更改为 ChannelWrapper

问题我觉得我应该创建一个额外的接口(interface)来匹配 ChannelChannelWrapper,并使用接口(interface)而不是可覆盖的成员进行模拟。同时,我真的看不出白白添加一个新界面有什么意义。

有什么理由更喜欢模拟接口(interface)而不是具有可覆盖成员的类?(我也主要考虑性能方面的问题)。

最佳答案

您通常想要模拟接口(interface)而不是具体类型的主要原因是,在具体类型的情况下,您的模拟将包含实际实现的点点滴滴,可能导致不可预测/不希望的行为。

例如,Channel 上的 Send 方法当前有“//Some stuff with TCP connection”。在里面。如果 Channel 类实例化一些 Web 连接并将它们存储为字段怎么办?这意味着您的模拟对象现在包含实际的 Web 连接,即使它们可能永远不会被使用。如果我们谈论数据库连接等,这可能会更严重。

在您的特定示例中可能不是这种情况,但您应该更多地考虑这次您已经“侥幸逃脱”,而不是成为规则。这些问题意味着模拟接口(interface)通常要干净得多;您知道您的模拟对象不包含您未在测试中放置的任何内容。

我也会看到这个非常相似的问题:Mocking classes that aren't interfaces

关于c# - 有什么理由更喜欢模拟接口(interface)而不是具有可覆盖成员的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21183364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com