是否有可以为现有类生成提取和生成接口的工具?
我知道 Visual Studio 将为现有类提取接口。但是,我还想生成一个实现该功能的包装器类。
我相信这对单元测试非常有帮助。
示例现有类:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
这可以由Visual Studio(提取界面)生成:
public interface IThirdPartyClass
{
void Method1();
void Method2();
}
我想更进一步:
public class ThirdPartyClassWrapper : IThirdPartyClass
{
private tpc = new ThirdPartyClass();
public void Method1()
{
tpc.Method1();
}
public void Method2()
{
tpc.Method2();
}
}
更新
这对静态类特别有用。正如莫滕指出我可以使用存根,但是,如果可能的话,我想打破我的耦合。
答案 0 :(得分:8)
找到了解决非密封类的方法。
1 - 从外部类继承
class MyWrapper : ExternalClass
2 - 提取所有公共方法的界面
class MyWrapper : ExternalClass, IExternalClass
3 - 从外部类中删除继承
class MyWrapper : IExternalClass
4 - 您将获得有关未实现的接口的成员的类名称的提示。按住Alt + Enter并让Resharper自动实现它们
5 - 使用此代码模板来包装属性
get { return $INNERCOMPONENT$.$NAME$; }
set { $INNERCOMPONENT$.$NAME$ = value; }
6 - 使用此代码模板包装方法
return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
答案 1 :(得分:3)
我不知道能为你做到这一点的工具。
您可能知道,但Visual Studio只是前进了一步 - 它可以提供接口的空实现。如果是一次性任务,我会在那里停下来。
根据实际目标,使用其他方式可能有效 - 即,对于测试,您可以使用模拟框架 - 通常有一种方法可以包装现有类并根据需要覆盖某些方法。
答案 2 :(得分:1)
另一种非常灵活的做法是使用Resharper来生成"委派成员"对于你的描述:https://stackoverflow.com/a/2150827/1703887
步骤:
创建一个新类,该类继承自您要使用该类的私有变量包装的类。类型:
public class ThirdPartyClassWrapper : ThirdPartyClass
{
private ThirdPartyClass _ThirdPartyClass;
}
在类中/上执行Alt-Insert以使用Resharper生成"委派成员"。选择要公开的方法并传递给私有变量。
如果您安装了GhostDoc extension的免费版本,则可以突出显示所有已创建的属性,方法等,并执行Ctrl-D以自动从基类中获取所有文档并把它放在新成员上。 (Resharper也可以这样做,但我认为你必须在每个项目上放置" new"然后允许你按Alt-Enter选择"添加xml-doc评论&#34 ;来自Resharper弹出菜单)。
然后,您可以删除基类并进行一些额外的清理,以防方法/属性签名暴露您需要包装的任何其他类型。
答案 3 :(得分:0)
你正在寻找的是一个存根,这可以通过制作你自己的接口的存根实现,或通过使用像Rhinomocks这样的模拟框架来完成。在另一个课程中为一个测试目的包装一个困难的课程对你没有任何好处。
此致 的Morten
答案 4 :(得分:0)
我强烈建议你研究像Fakeiteasy这样的模拟框架。
但要准确地告诉你你的要求,请参阅下文。我怀疑当其他人回答时,ReSharper没有这个操作。
将接口添加到您希望成为包装类的类
class MyWebElement : IWebElement { }
点击完成并享受您的新课程
class MyWebElement : IWebElement
{
private IWebElement _webElementImplementation;
public IWebElement FindElement(By @by)
{
return _webElementImplementation.FindElement(@by);
}
public ReadOnlyCollection<IWebElement> FindElements(By @by)
{
return _webElementImplementation.FindElements(@by);
}
public void Clear()
{
_webElementImplementation.Clear();
}
public void SendKeys(string text)
{
_webElementImplementation.SendKeys(text);
}
public void Submit()
{
_webElementImplementation.Submit();
}
public void Click()
{
_webElementImplementation.Click();
}
public string GetAttribute(string attributeName)
{
return _webElementImplementation.GetAttribute(attributeName);
}
public string GetCssValue(string propertyName)
{
return _webElementImplementation.GetCssValue(propertyName);
}
public string TagName
{
get { return _webElementImplementation.TagName; }
}
public string Text
{
get { return _webElementImplementation.Text; }
}
public bool Enabled
{
get { return _webElementImplementation.Enabled; }
}
public bool Selected
{
get { return _webElementImplementation.Selected; }
}
public Point Location
{
get { return _webElementImplementation.Location; }
}
public Size Size
{
get { return _webElementImplementation.Size; }
}
public bool Displayed
{
get { return _webElementImplementation.Displayed; }
}
}