C# .NET工具:提取接口并实现包装器类
是否有一个工具可以为现有类生成提取和生成接口 我知道VisualStudio将为现有类提取接口。但是,我还想生成一个实现该功能的包装器类 我相信这对单元测试有很大帮助 现有类示例:C# .NET工具:提取接口并实现包装器类,c#,unit-testing,interface,wrapper,C#,Unit Testing,Interface,Wrapper,是否有一个工具可以为现有类生成提取和生成接口 我知道VisualStudio将为现有类提取接口。但是,我还想生成一个实现该功能的包装器类 我相信这对单元测试有很大帮助 现有类示例: public class ThirdPartyClass { public void Method1(){} public void Method2(){} } public interface IThirdPartyClass { void Method1(); void Method2(
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
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();
}
}
这可以由Visual Studio生成(提取界面):
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
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();
}
}
我想更进一步:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
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();
}
}
更新:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
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();
}
}
这对于静态类特别有用。正如莫顿指出的那样,我可以只使用一个存根,但是,如果可能的话,我想断开我的耦合。我不知道有什么工具可以为您做到这一点 您可能知道,但VisualStudio只前进了半步——它可以提供接口的空实现。如果是一次性任务,我就到此为止
根据实际目标,使用其他方法可能会起作用-例如,对于测试,您可以使用模拟框架-通常有一种方法可以包装现有类并根据需要重写某些方法。您需要的是存根,这可以通过创建自己的接口存根实现来实现,或者使用类似Rhinomock的模拟框架。为了测试目的,在另一个类中包装一个困难的类对您没有任何好处 问候
Morten找到了一种解决非密封类问题的方法 1-从外部类继承
class MyWrapper : ExternalClass
class MyWrapper : IExternalClass
2-提取所有公共方法的接口
class MyWrapper : ExternalClass, IExternalClass
3-从外部类中删除继承
class MyWrapper : ExternalClass
class MyWrapper : IExternalClass
4-您将从未实现的接口中获得有关成员的类名提示。Alt+Enter并让Resharper自动实现它们
5-使用此代码模板包装属性
get { return $INNERCOMPONENT$.$NAME$; }
set { $INNERCOMPONENT$.$NAME$ = value; }
6-使用此代码模板包装方法
return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
另一种非常巧妙的方法是使用Resharper为您生成“委派成员”,如下所述: 步骤:
public class ThirdPartyClassWrapper : ThirdPartyClass
{
private ThirdPartyClass _ThirdPartyClass;
}
我强烈建议您研究类似FakeiTasy的模拟框架 但要给你你想要的,请看下文。我怀疑其他人接电话时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; }
}
}
类MyWebElement:IWebElement
{
私有iWebElementu WebElement实现;
公共IWebElement FindElement(By@By)
{
返回_webElementImplementation.FindElement(@by);
}
公共只读集合FindElements(By@By)
{
返回_webElementImplementation.FindElements(@by);
}
公共空间清除()
{
_webElementImplementation.Clear();
}
公用void发送键(字符串文本)
{
_webElementImplementation.SendKeys(文本);
}
公开作废提交()
{
_webElementImplementation.Submit();
}
公共作废点击()
{
_webElementImplementation.Click();
}
公共字符串GetAttribute(字符串attributeName)
{
返回webElementImplementation.GetAttribute(attributeName);
}
公共字符串GetCssValue(字符串属性名称)
{
返回webElementImplementation.GetCssValue(propertyName);
}
公共字符串标记名
{
获取{return\u webElementImplementation.TagName;}
}
公共字符串文本
{
获取{return\u webElementImplementation.Text;}
}
公共布尔启用
{
获取{return\u webElementImplementation.Enabled;}
}
公共图书馆获选
{
获取{return\u webElementImplementation.Selected;}
}
公共点位置
{
获取{return\u webElementImplementation.Location;}
}
公共大小
{
获取{return\u webElementImplementation.Size;}
}
公开展览
{
获取{return\u webElementImplementation.Displayed;}
}
}
“将一个困难的类包装到另一个类中进行测试对您没有任何好处。“我认为这将减少耦合,并允许以后的自定义实现。是的,但为什么不现在就存根接口,让它作为测试的输入?如果您正在使用这个实现,那么您也在测试它,使您的测试成为一个集成测试。但是,我无法存根一个静态类。撇开测试不谈,我认为以后它会真正受益。如果输入类是静态的,那么可以通过委托注入静态函数。因此,在测试时,在静态类中使用方法可以替换为非静态/存根实现。关于它的任何解决方案都可以在这里找到完全相同的答案。我对这个问题投赞成票,再次投反对票。EF或VS应具有此选项。