将委托方法存储为类的成员

时间:2012-05-11 13:20:59

标签: c# delegates

我正在进行编码ui测试,基本上是ui的单元测试,我创建了一个TestObject类,它存储了一个在TestMethod中对其自身执行的断言列表,实例化它。

public class TestObject {
    public string urlToTest;
    public List<Assertion> assertions;
}

public class Assertion {
    public List<SearchPropertyExpression> searchPropertyExpressions;
    public Action assertMethod;
    public string expectedValue; // <-- this works fine if I'll always call a method like AreEqual() where it has an expected value, but what if I want to store a method in assertMethod that has different arguments???
}

public class SearchPropertyExpression {
    public string expression;
    public string value;
}

我想存储断言方法(例如:我想要针对特定​​Assert.AreEqaul(object expected, object actual)执行的TestObject并稍后调用,但我正在努力获得语法正确的东西。我在实际调用它时,我还在努力如何传递该委托方法(assertMethod)的参数。我将调用的所有方法都在Microsoft.VisualStudio.TestTools.UnitTesting.Assert内。在下面的例子中我想调用Assert.AreEqaul()但是可以调用任何具有不同参数的方法。这是我到目前为止所得到的......

[TestMethod]
public void uiTestConnectionsEducationHomePage() {
    //instantiate test object
    TestObject testObject = new TestObject() {
        urlToTest = "/example/home.aspx",
        assertions = {
            new Assertion() {
                searchPropertyExpressions = {
                    new SearchPropertyExpression() {
                        expression = HtmlDiv.PropertyNames.Id,
                        value = "header"
                    }
                },
                assertMethod = Assert.AreEqual // <-- this is wrong,I'm thinking I need to tell assertMethod what arguments to expect here, lambda??
            }
        }
    };

    // get handle to browser and launch
    UiBrowserWindow uiBrowserWindow = new UiBrowserWindow();
    uiBrowserWindow.launchUrl(testObject.urlToTest);

    // assertions
    testObject.assertions.ForEach(x => {
        HtmlDiv htmlObject = new HtmlDiv();
        x.searchPropertyExpressions.ForEach(p => {
            htmlObject = uiBrowserWindow.uiHtmlDocument.searchHtmlElementByAttributeValue<HtmlDiv>(p.expression, p.value);
        });
        x.assertMethod; // <-- for this is example the arguments would be (htmlObject, "header").                   
    });
}

我认为我的真正问题是这里有一种设计模式可以帮助我,但我并不精通设计模式。

2 个答案:

答案 0 :(得分:3)

您的assertMethod委托类型为Action,表示返回类型为void且没有参数的方法,例如void Foo()
Assert.AreEqualmany overloads,最普遍的是Assert.AreEqual(Object expected, Object actual)。我建议你使用它并相应地更改你的代表:

Action<Object, Object> assertMethod;

答案 1 :(得分:0)

如果您希望代理指向任何方法定义,您可以执行类似的操作: -

public delegate void MyAction(params object[] args);
public class Assertion
{
    public List<PropertyExpression> propertyExpressions;
    public MyAction assertMethod;
}
public void Test()
{
   var asser = new Assertion()
                    {
                        assertMethod = (vals) =>Assert.AreEqual(vals[0],vals[1]);
                        propertyExpressions = null
                    };
   var asser2 = new Assertion()
                    {
                        assertMethod = (vals)=>Assert.AreEqual((string)vals[0],(string)vals[1],(bool)vals[2]);
                        propertyExpressions = null
                    };

    asser.assertMethod(1, 1);//calling object,object overload
    asser2.assertMethod("ab", "cd", true);//calling string,string,bool overload
}