C# 测试从抽象类使用的方法
我必须对一个方法(runMethod())进行单元测试,该方法使用来自固有抽象类的方法来创建布尔值。抽象类中的方法使用XmlDocuments和节点来检索信息。代码看起来有点像这样(这是非常简化的,但它说明了我的问题) 因此,代码希望从创建的XmlDocument中获取属性,并使用它将结果形成布尔值。现在我的问题是,什么是确保我能控制布尔结果行为的最佳解决方案。我用最小起订量来模拟 我知道这个代码示例可能有点模糊,但这是我能展示的最好的例子。希望你们能帮忙 编辑:我基本上需要的是:C# 测试从抽象类使用的方法,c#,unit-testing,mocking,dependencies,abstract,C#,Unit Testing,Mocking,Dependencies,Abstract,我必须对一个方法(runMethod())进行单元测试,该方法使用来自固有抽象类的方法来创建布尔值。抽象类中的方法使用XmlDocuments和节点来检索信息。代码看起来有点像这样(这是非常简化的,但它说明了我的问题) 因此,代码希望从创建的XmlDocument中获取属性,并使用它将结果形成布尔值。现在我的问题是,什么是确保我能控制布尔结果行为的最佳解决方案。我用最小起订量来模拟 我知道这个代码示例可能有点模糊,但这是我能展示的最好的例子。希望你们能帮忙 编辑:我基本上需要的是: 我需要能够在
我需要能够在测试AbstractInheret类时控制getProperty()如果我正确理解了您的问题,您想知道如何控制getProperty的结果,以便可以测试具有不同布尔值的附加内容 如果您在为某个东西编写测试时遇到困难,这通常意味着您试图测试太多,或者代码设计有问题 通过避免使用继承,您可以使此代码更易于测试。正如您所发现的,在单元测试中继承通常很难处理(存在很多紧密耦合),而且委托通常工作得更好。我建议对设计进行以下更改:
namespace TestExample
{
public interface PropertyManager {
public string getProperty(string propertyName);
}
public class XmlPropertyManager: PropertyManager {
public string getProperty(string propertyName) {
//...xml parsing code here
}
}
public class Example {
private PropertyManager propertyManager;
public void runMethod() {
bool addIfContains = (propertyManager.getProperty("AddIfContains") == null || propertyManager.getProperty("AddIfContains") == "True");
//Do something with boolean
}
}
}
然后,您可以轻松模拟PropertyManager
如果设计要求使用抽象基类(用于除getProperty之外的其他函数),则仍然可以使用委托方法:
namespace TestExample
{
public interface PropertyManager {
public string getProperty(string propertyName);
}
public class XmlPropertyManager: PropertyManager {
public string getProperty(string propertyName) {
//...xml parsing code here
}
}
public abstract class AbstractExample
{
protected PropertyManager propertyManager;
//... other important methods
}
public class AbstractInheret: AbstractExample {
public void runMethod() {
bool addIfContains = (propertyManager.getProperty("AddIfContains") == null || propertyManager.getProperty("AddIfContains") == "True");
//Do something with boolean
}
}
}
我不太清楚你这个问题的确切意思- “确保我能控制布尔人的结果行为的最佳解决方案是什么。” 我猜您需要属性的布尔值。所以,这可能就行了
public static bool GetBoolean(string boolStr)
{
bool bVal = default(bool);
try
{
bVal = Convert.ToBoolean(boolStr);
}
catch (Exception) {
bVal = default(bool);
}
return bVal;
}
只需将其插入代码,它就应该很好了。:) 由于布尔值由xml控制,因此可以重构代码,以便轻松设置xml 像这样:
namespace AbstractTestExample
{
public abstract class AbstractExample
{
protected XmlNode propertyValuesXML;
protected string getProperty(string propertyName)
{
XmlNode node = propertyValuesXML.FirstChild.SelectSingleNode(String.Format("property[name='{0}']/value", propertyName));
return node.InnerText;
}
}
public class AbstractInheret : AbstractExample
{
public AbstractInheret(string propertyValues){
propertyValuesXML = new XmlDocument();
propertyValuesXML.Load(new System.IO.StringReader(propertyValues));
}
public void runMethod()
{
bool addIfContains = (getProperty("AddIfContains") == null || getProperty("AddIfContains") == "True");
//Do something with boolean
}
}
}
这样,您就不必模仿任何东西,并且可以轻松地将xml字符串传递给类。您还应该检查是否存在涉及传递给构造函数的无效xml的错误情况。如果由于某种原因无法按照我的第一个答案中描述的方式重构代码(例如第三方提供抽象基类),那么您可以创建AbstractInherit的子类,该子类仅覆盖getProperty方法。请注意,我确实不喜欢这种方法,因为它将测试与类的内部实现相结合。但有时你别无选择。你的方法很有趣,吉姆:]我喜欢它,但不确定我是否能在实现中使用它。我试试看。如果成功,我会让你知道/接受你的答案。谢谢你的回复!我将替代方法移到另一个答案,以便清楚地知道您选择使用哪种解决方案。我还添加了一个示例,说明如何在使用委托的同时仍然使用抽象基类。我跟进了JJoos的示例,它提出了使用字典的解决方案。使用propertyName作为键,propertyValue作为值:]现在我不再使用getProperty(“键”),而是使用Dictionary[“key”]。谢谢你的反馈!它确实有帮助,但我必须为它重构许多代码>。获取布尔值不是问题:]问题是:我如何控制它的结果。由于依赖关系,我不能在测试中说:addIfContains=true或addIfContains=false。这就是我需要模拟/存根的地方。因此,我的问题是:当我的类使用从抽象类中继承的方法,并且使用未被注入的Xml依赖时,您如何处理这个问题。我恐怕无法理解您的问题。除非有更多关于“依赖性”和“需要模仿”的细节……好吧,我必须同意你的观点,我试图解释的情况也很难(而且很难在简单的上下文中解释)。但我基本上是在寻找吉姆提议的东西。当我测试AbstractInheret类“How”时,我需要能够控制getProperty(),您希望如何控制函数getProperty?接口/模拟还是通过重构。这仅用于单元测试目的
namespace AbstractTestExample
{
public abstract class AbstractExample
{
protected XmlNode propertyValuesXML;
protected string getProperty(string propertyName)
{
XmlNode node = propertyValuesXML.FirstChild.SelectSingleNode(String.Format("property[name='{0}']/value", propertyName));
return node.InnerText;
}
}
public class AbstractInheret : AbstractExample
{
public AbstractInheret(string propertyValues){
propertyValuesXML = new XmlDocument();
propertyValuesXML.Load(new System.IO.StringReader(propertyValues));
}
public void runMethod()
{
bool addIfContains = (getProperty("AddIfContains") == null || getProperty("AddIfContains") == "True");
//Do something with boolean
}
}
}