0

我必须对一个方法 (runMethod()) 进行单元测试,该方法使用继承的抽象类中的方法来创建布尔值。抽象类中的方法使用 XmlDocuments 和节点来检索信息。代码看起来有点像这样(这非常简化,但它说明了我的问题)

namespace AbstractTestExample
{
public abstract class AbstractExample
{
    public string propertyValues;
    protected XmlNode propertyValuesXML;
    protected string getProperty(string propertyName)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(new System.IO.StringReader(propertyValues));
        propertyValuesXML= doc.FirstChild;

        XmlNode node = propertyValuesXML.SelectSingleNode(String.Format("property[name='{0}']/value", propertyName));
        return node.InnerText;
    }
}

public class AbstractInheret : AbstractExample
{
    public void runMethod()
    {
        bool addIfContains = (getProperty("AddIfContains") == null || getProperty("AddIfContains") == "True");
        //Do something with boolean
    }
}
}

因此,代码想要从创建的 XmlDocument 中获取一个属性,并使用它将结果形成一个布尔值。现在我的问题是,确保我可以控制布尔结果行为的最佳解决方案是什么。我正在使用 Moq 进行可能的模拟。

我知道这个代码示例可能有点模糊,但这是我能展示的最好的。希望大家能帮忙。

编辑:我基本上需要的是:
我需要能够在测试 AbstractInheret 类时控制 getProperty()

4

4 回答 4

1

由于布尔值由 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 的错误情况。

于 2010-04-15T08:48:33.110 回答
0

如果我正确理解您的问题,您想知道如何控制 getProperty 的结果,以便您可以使用不同的布尔值测试 addIfContains。

如果您在为某事编写测试时遇到困难,这通常意味着您尝试测试太多,或者代码设计存在问题。

通过避免使用继承,您也许可以使此代码更具可测试性。正如您所发现的,在单元测试中继承通常很难处理(有很多紧耦合正在进行),而且委托通常工作得更好。我建议对设计进行以下更改:

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
      }
    }
}
于 2010-04-14T12:22:36.530 回答
0

我不太确定这个问题到底是什么意思-

“确保我可以控制布尔结果行为的最佳解决方案是什么。”

我猜你需要一个属性的布尔值。所以,这可能就行了!

    public static bool GetBoolean(string boolStr)
    {
        bool bVal = default(bool);
        try
        {
            bVal = Convert.ToBoolean(boolStr);
        }
        catch (Exception) {
            bVal = default(bool);
        }
        return bVal;
    }

只需将其插入代码,它应该是好的。:)

于 2010-04-14T13:08:23.543 回答
0

如果由于某种原因您无法按照我的第一个答案中描述的方式重构代码(例如第三方提供抽象基类),那么您可以创建 AbstractInherit 的子类,它仅覆盖 getProperty 方法。请注意,我真的不喜欢这种方法,因为它将您的测试与类的内部实现结合在一起。但有时你别无选择。

于 2010-04-15T12:04:14.823 回答